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)#ifndef EXTENSIONS_BROWSER_EVENT_ROUTER_H_ 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define EXTENSIONS_BROWSER_EVENT_ROUTER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/scoped_observer.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_listener_map.h" 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/extension_registry_observer.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/event_filtering_info.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sender.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GURL; 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class PrefService; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BrowserContext; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderProcessHost; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ActivityLog; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Extension; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionHost; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionPrefs; 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ExtensionRegistry; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Event; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct EventDispatchInfo; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct EventListenerInfo; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EventRouter : public content::NotificationObserver, 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public ExtensionRegistryObserver, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public EventListenerMap::Delegate { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These constants convey the state of our knowledge of whether we're in 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a user-caused gesture as part of DispatchEvent. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum UserGestureState { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USER_GESTURE_UNKNOWN = 0, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USER_GESTURE_ENABLED = 1, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USER_GESTURE_NOT_ENABLED = 2, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The pref key for the list of event names for which an extension has 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // registered from its lazy background page. 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static const char kRegisteredEvents[]; 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Observers register interest in events with a particular name and are 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // notified when a listener is added or removed. Observers are matched by 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the base name of the event (e.g. adding an event listener for event name 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // "foo.onBar/123" will trigger observers registered for "foo.onBar"). 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Observer { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a listener is added. 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnListenerAdded(const EventListenerInfo& details) {} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a listener is removed. 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnListenerRemoved(const EventListenerInfo& details) {} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Gets the EventRouter for |browser_context|. 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Shorthand for ExtensionSystem::Get(browser_context)->event_router(); it's 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // a very common operation. 77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch static EventRouter* Get(content::BrowserContext* browser_context); 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Converts event names like "foo.onBar/123" into "foo.onBar". Event names 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // without a "/" are returned unchanged. 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static std::string GetBaseEventName(const std::string& full_event_name); 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sends an event via ipc_sender to the given extension. Can be called on any 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void DispatchEvent(IPC::Sender* ipc_sender, 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void* browser_context_id, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::ListValue> event_args, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UserGestureState user_gesture, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EventFilteringInfo& info); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // An EventRouter is shared between |browser_context| and its associated 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // incognito context. |extension_prefs| may be NULL in tests. 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EventRouter(content::BrowserContext* browser_context, 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionPrefs* extension_prefs); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~EventRouter(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Add or remove an extension as an event listener for |event_name|. 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that multiple extensions can share a process due to process 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // collapsing. Also, a single extension can have 2 processes if it is a split 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mode extension. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddEventListener(const std::string& event_name, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveEventListener(const std::string& event_name, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Add or remove a URL as an event listener for |event_name|. 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void AddEventListenerForURL(const std::string& event_name, 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::RenderProcessHost* process, 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& listener_url); 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void RemoveEventListenerForURL(const std::string& event_name, 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::RenderProcessHost* process, 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& listener_url); 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListenerMap& listeners() { return listeners_; } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Registers an observer to be notified when an event listener for 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |event_name| is added or removed. There can currently be only one observer 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for each distinct |event_name|. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RegisterObserver(Observer* observer, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unregisters an observer from all events. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UnregisterObserver(Observer* observer); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add or remove the extension as having a lazy background page that listens 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the event. The difference from the above methods is that these will be 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // remembered even after the process goes away. We use this list to decide 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which extension pages to load when dispatching an event. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddLazyEventListener(const std::string& event_name, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveLazyEventListener(const std::string& event_name, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |add_lazy_listener| is true also add the lazy version of this listener. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddFilteredEventListener(const std::string& event_name, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue& filter, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool add_lazy_listener); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |remove_lazy_listener| is true also remove the lazy version of this 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // listener. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveFilteredEventListener(const std::string& event_name, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue& filter, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool remove_lazy_listener); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if there is at least one listener for the given event. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasEventListener(const std::string& event_name); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the extension is listening to the given event. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ExtensionHasEventListener(const std::string& extension_id, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Return or set the list of events for which the given extension has 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // registered. 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<std::string> GetRegisteredEvents(const std::string& extension_id); 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SetRegisteredEvents(const std::string& extension_id, 16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::set<std::string>& events); 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Broadcasts an event to every listener registered for that event. 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void BroadcastEvent(scoped_ptr<Event> event); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Dispatches an event to the given extension. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DispatchEventToExtension(const std::string& extension_id, 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Event> event); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Dispatches |event| to the given extension as if the extension has a lazy 175ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // listener for it. NOTE: This should be used rarely, for dispatching events 176ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // to extensions that haven't had a chance to add their own listeners yet, eg: 177ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // newly installed extensions. 178ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch void DispatchEventWithLazyListener(const std::string& extension_id, 179ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<Event> event); 180ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record the Event Ack from the renderer. (One less event in-flight.) 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void OnEventAck(content::BrowserContext* context, 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& extension_id); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) friend class EventRouterTest; 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension and process that contains the event listener for a given 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ListenerProcess; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A map between an event name and a set of extensions that are listening 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to that event. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An identifier for an event dispatch that is used to prevent double dispatch 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // due to race conditions between the direct and lazy dispatch paths. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::pair<const content::BrowserContext*, std::string> 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventDispatchIdentifier; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(gdk): Document this. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void DispatchExtensionMessage( 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Sender* ipc_sender, 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void* browser_context_id, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ListValue* event_args, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UserGestureState user_gesture, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::EventFilteringInfo& info); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Observe(int type, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // ExtensionRegistryObserver implementation. 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void OnExtensionLoaded(content::BrowserContext* browser_context, 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension) OVERRIDE; 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void OnExtensionUnloaded( 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserContext* browser_context, 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const Extension* extension, 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UnloadedExtensionInfo::Reason reason) OVERRIDE; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the given listener map contains a event listeners for 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the given event. If |extension_id| is non-empty, we also check that that 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension is one of the listeners. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasEventListenerImpl(const ListenerMap& listeners, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_name); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shared by DispatchEvent*. If |restrict_to_extension_id| is empty, the 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event is broadcast. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An event that just came off the pending list may not be delayed again. 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DispatchEventImpl(const std::string& restrict_to_extension_id, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const linked_ptr<Event>& event); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensures that all lazy background pages that are interested in the given 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event are loaded, and queues the event if the page is not ready yet. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event dispatch that is queued. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DispatchLazyEvent(const std::string& extension_id, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const linked_ptr<Event>& event, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<EventDispatchIdentifier>* already_dispatched); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Dispatches the event to the specified extension or URL running in 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |process|. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DispatchEventToProcess(const std::string& extension_id, 2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& listener_url, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const linked_ptr<Event>& event); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Returns false when the event is scoped to a context and the listening 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // extension does not have access to events from that context. Also fills 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |event_args| with the proper arguments to send, which may differ if 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the event crosses the incognito boundary. 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool CanDispatchEventToBrowserContext(content::BrowserContext* context, 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension, 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const linked_ptr<Event>& event); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Possibly loads given extension's background page in preparation to 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dispatch an event. Returns true if the event was queued for subsequent 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dispatch, false otherwise. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool MaybeLoadLazyBackgroundPageToDispatchEvent( 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* context, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const linked_ptr<Event>& event); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Adds a filter to an event. 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void AddFilterToEvent(const std::string& event_name, 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id, 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::DictionaryValue* filter); 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Removes a filter from an event. 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void RemoveFilterFromEvent(const std::string& event_name, 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id, 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::DictionaryValue* filter); 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Returns the dictionary of event filters that the given extension has 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // registered. 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::DictionaryValue* GetFilteredEvents( 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id); 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Track of the number of dispatched events that have not yet sent an 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ACK from the renderer. 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void IncrementInFlightEvents(content::BrowserContext* context, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // static 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static void IncrementInFlightEventsOnUI( 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void* browser_context_id, 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& extension_id); 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DispatchPendingEvent(const linked_ptr<Event>& event, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Implementation of EventListenerMap::Delegate. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnListenerAdded(const EventListener* listener) OVERRIDE; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnListenerRemoved(const EventListener* listener) OVERRIDE; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* browser_context_; 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The ExtensionPrefs associated with |browser_context_|. May be NULL in 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // tests. 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionPrefs* extension_prefs_; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension_registry_observer_; 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventListenerMap listeners_; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Map from base event name to observer. 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef base::hash_map<std::string, Observer*> ObserverMap; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObserverMap observers_; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(EventRouter); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Event { 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) typedef base::Callback<void(content::BrowserContext*, 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension*, 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::ListValue*)> WillDispatchCallback; 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The event to dispatch. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_name; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Arguments to send to the event listener. 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::ListValue> event_args; 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If non-NULL, then the event will not be sent to other BrowserContexts 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // unless the extension has permission (e.g. incognito tab update -> normal 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // tab only works if extension is allowed incognito access). 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* restrict_to_browser_context; 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If not empty, the event is only sent to extensions with host permissions 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for this url. 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL event_url; 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether a user gesture triggered the event. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventRouter::UserGestureState user_gesture; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Extra information used to filter which events are sent to the listener. 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventFilteringInfo filter_info; 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If specified, this is called before dispatching an event to each 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extension. The third argument is a mutable reference to event_args, 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // allowing the caller to provide different arguments depending on the 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extension and profile. This is guaranteed to be called synchronously with 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // DispatchEvent, so callers don't need to worry about lifetime. 3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // 3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // NOTE: the Extension argument to this may be NULL because it's possible for 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // this event to be dispatched to non-extension processes, like WebUI. 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WillDispatchCallback will_dispatch_callback; 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Event(const std::string& event_name, 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> event_args); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Event(const std::string& event_name, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::ListValue> event_args, 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* restrict_to_browser_context); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Event(const std::string& event_name, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::ListValue> event_args, 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* restrict_to_browser_context, 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& event_url, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventRouter::UserGestureState user_gesture, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EventFilteringInfo& info); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Event(); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Makes a deep copy of this instance. Ownership is transferred to the 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // caller. 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Event* DeepCopy(); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct EventListenerInfo { 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventListenerInfo(const std::string& event_name, 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& extension_id, 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL& listener_url, 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* browser_context); 380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The event name including any sub-event, e.g. "runtime.onStartup" or 381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // "webRequest.onCompleted/123". 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string event_name; 383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string extension_id; 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL listener_url; 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::BrowserContext* browser_context; 387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_ 392