blob: 140d84837d52e1cbd04981246056922436726473 [file] [log] [blame]
[email protected]9e6720a2012-01-24 02:30:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]2c699652010-10-15 18:22:412// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]34423532013-11-21 18:13:105#ifndef EXTENSIONS_BROWSER_EVENT_ROUTER_H_
6#define EXTENSIONS_BROWSER_EVENT_ROUTER_H_
[email protected]2c699652010-10-15 18:22:417
[email protected]2c699652010-10-15 18:22:418#include <set>
9#include <string>
thestig7ade5b52017-05-23 23:13:3610#include <unordered_map>
[email protected]2c699652010-10-15 18:22:4111
[email protected]6e850922012-12-05 03:22:4812#include "base/callback.h"
[email protected]17902752011-08-31 22:52:5413#include "base/compiler_specific.h"
avic9cec102015-12-23 00:39:2614#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1515#include "base/memory/ref_counted.h"
lazyboye464732f2017-06-15 21:17:2716#include "base/memory/weak_ptr.h"
Devlin Croninffbd2fe22018-07-20 17:20:1717#include "base/observer_list.h"
[email protected]4243f9a2014-08-04 18:53:1218#include "base/scoped_observer.h"
[email protected]8a16a032012-06-18 19:37:3119#include "base/values.h"
juncaicf523332015-06-04 00:14:0420#include "components/keyed_service/core/keyed_service.h"
amistry69e9ee422015-05-22 07:40:2521#include "content/public/browser/render_process_host_observer.h"
[email protected]a0e26d42013-11-20 07:04:0422#include "extensions/browser/event_listener_map.h"
Istiaque Ahmeda14ec482018-08-25 01:02:1823#include "extensions/browser/events/event_ack_data.h"
lazyboy75b9def2017-06-06 18:56:5924#include "extensions/browser/events/lazy_event_dispatch_util.h"
kalmanf1b4d782015-06-24 21:14:0525#include "extensions/browser/extension_event_histogram_value.h"
[email protected]4243f9a2014-08-04 18:53:1226#include "extensions/browser/extension_registry_observer.h"
lazyboy63b994a2017-06-30 21:20:2327#include "extensions/browser/lazy_context_task_queue.h"
lazyboye7847242017-06-07 23:29:1828#include "extensions/common/constants.h"
[email protected]4b3e1922013-02-12 04:45:5829#include "extensions/common/event_filtering_info.h"
[email protected]b44f8ad2012-06-15 20:52:5830#include "ipc/ipc_sender.h"
kalmana9f6e67a2015-08-11 00:22:5031#include "url/gurl.h"
[email protected]2c699652010-10-15 18:22:4132
33class GURL;
Istiaque Ahmed9d1666182017-09-21 23:58:1834struct ServiceWorkerIdentifier;
[email protected]f3b1a082011-11-18 00:34:3035
36namespace content {
[email protected]7061be92013-02-18 15:44:0237class BrowserContext;
[email protected]2c699652010-10-15 18:22:4138class RenderProcessHost;
[email protected]f3b1a082011-11-18 00:34:3039}
[email protected]2c699652010-10-15 18:22:4140
[email protected]1c321ee52012-05-21 03:02:3441namespace extensions {
42class Extension;
[email protected]79cb81bb2012-09-20 02:23:3143class ExtensionPrefs;
[email protected]4243f9a2014-08-04 18:53:1244class ExtensionRegistry;
[email protected]3a1dc572012-07-31 22:25:1345
[email protected]5a38dfd2012-07-23 23:22:1046struct Event;
[email protected]954e13492012-11-15 03:18:2347struct EventListenerInfo;
[email protected]1c321ee52012-05-21 03:02:3448
lazyboye7847242017-06-07 23:29:1849// TODO(lazyboy): Document how extension events work, including how listeners
50// are registered and how listeners are tracked in renderer and browser process.
juncaicf523332015-06-04 00:14:0451class EventRouter : public KeyedService,
[email protected]4243f9a2014-08-04 18:53:1252 public ExtensionRegistryObserver,
amistry69e9ee422015-05-22 07:40:2553 public EventListenerMap::Delegate,
54 public content::RenderProcessHostObserver {
[email protected]2c699652010-10-15 18:22:4155 public:
[email protected]b085856f2012-03-02 04:37:2556 // These constants convey the state of our knowledge of whether we're in
57 // a user-caused gesture as part of DispatchEvent.
58 enum UserGestureState {
59 USER_GESTURE_UNKNOWN = 0,
60 USER_GESTURE_ENABLED = 1,
61 USER_GESTURE_NOT_ENABLED = 2,
62 };
63
[email protected]e74d43c72013-05-17 19:01:4164 // The pref key for the list of event names for which an extension has
65 // registered from its lazy background page.
lazyboye7847242017-06-07 23:29:1866 static const char kRegisteredLazyEvents[];
67 // The pref key for the list of event names for which an extension has
68 // registered from its service worker.
69 static const char kRegisteredServiceWorkerEvents[];
[email protected]e74d43c72013-05-17 19:01:4170
[email protected]c4dc5cc2012-11-09 08:48:3971 // Observers register interest in events with a particular name and are
[email protected]c761a962013-11-20 04:19:4172 // notified when a listener is added or removed. Observers are matched by
73 // the base name of the event (e.g. adding an event listener for event name
74 // "foo.onBar/123" will trigger observers registered for "foo.onBar").
[email protected]c4dc5cc2012-11-09 08:48:3975 class Observer {
76 public:
77 // Called when a listener is added.
[email protected]954e13492012-11-15 03:18:2378 virtual void OnListenerAdded(const EventListenerInfo& details) {}
[email protected]c4dc5cc2012-11-09 08:48:3979 // Called when a listener is removed.
[email protected]954e13492012-11-15 03:18:2380 virtual void OnListenerRemoved(const EventListenerInfo& details) {}
thestig7ade5b52017-05-23 23:13:3681
82 protected:
83 virtual ~Observer() {}
[email protected]c4dc5cc2012-11-09 08:48:3984 };
85
Devlin Croninffbd2fe22018-07-20 17:20:1786 // A test observer to monitor event dispatching.
87 class TestObserver {
88 public:
89 virtual ~TestObserver() = default;
90 virtual void OnWillDispatchEvent(const Event& event) = 0;
Ramin Halavatia4870222018-07-31 05:41:0491 virtual void OnDidDispatchEventToProcess(const Event& event) = 0;
Devlin Croninffbd2fe22018-07-20 17:20:1792 };
93
[email protected]3a368a22014-03-26 19:29:1994 // Gets the EventRouter for |browser_context|.
[email protected]3a368a22014-03-26 19:29:1995 static EventRouter* Get(content::BrowserContext* browser_context);
96
[email protected]c761a962013-11-20 04:19:4197 // Converts event names like "foo.onBar/123" into "foo.onBar". Event names
98 // without a "/" are returned unchanged.
99 static std::string GetBaseEventName(const std::string& full_event_name);
100
[email protected]c9bd90f2012-08-07 23:58:15101 // Sends an event via ipc_sender to the given extension. Can be called on any
102 // thread.
kalmana9f6e67a2015-08-11 00:22:50103 //
104 // It is very rare to call this function directly. Instead use the instance
105 // methods BroadcastEvent or DispatchEventToExtension.
106 static void DispatchEventToSender(IPC::Sender* ipc_sender,
107 void* browser_context_id,
David Bertonifc97d5ea2019-03-20 04:08:39108 int render_process_id,
kalmana9f6e67a2015-08-11 00:22:50109 const std::string& extension_id,
110 events::HistogramValue histogram_value,
111 const std::string& event_name,
David Bertonifc97d5ea2019-03-20 04:08:39112 int64_t service_worker_version_id,
dchengf5d241082016-04-21 03:43:11113 std::unique_ptr<base::ListValue> event_args,
kalmana9f6e67a2015-08-11 00:22:50114 UserGestureState user_gesture,
115 const EventFilteringInfo& info);
[email protected]5a7b5eaf2010-11-02 20:52:19116
lazyboye464732f2017-06-15 21:17:27117 // Returns false when the event is scoped to a context and the listening
118 // extension does not have access to events from that context.
119 static bool CanDispatchEventToBrowserContext(content::BrowserContext* context,
120 const Extension* extension,
121 const Event& event);
122
[email protected]45fd94172013-11-13 03:29:52123 // An EventRouter is shared between |browser_context| and its associated
124 // incognito context. |extension_prefs| may be NULL in tests.
125 EventRouter(content::BrowserContext* browser_context,
126 ExtensionPrefs* extension_prefs);
dcheng9168b2f2014-10-21 12:38:24127 ~EventRouter() override;
[email protected]2c699652010-10-15 18:22:41128
[email protected]c1abb3232014-07-30 18:28:39129 // Add or remove an extension as an event listener for |event_name|.
130 //
[email protected]a7ab1b782010-10-21 23:24:16131 // Note that multiple extensions can share a process due to process
132 // collapsing. Also, a single extension can have 2 processes if it is a split
133 // mode extension.
[email protected]2c699652010-10-15 18:22:41134 void AddEventListener(const std::string& event_name,
[email protected]f3b1a082011-11-18 00:34:30135 content::RenderProcessHost* process,
lazyboye7847242017-06-07 23:29:18136 const ExtensionId& extension_id);
137 void AddServiceWorkerEventListener(const std::string& event_name,
138 content::RenderProcessHost* process,
139 const ExtensionId& extension_id,
lazyboy63b994a2017-06-30 21:20:23140 const GURL& service_worker_scope,
Istiaque Ahmeda14ec482018-08-25 01:02:18141 int64_t service_worker_version_id,
lazyboye7847242017-06-07 23:29:18142 int worker_thread_id);
[email protected]2c699652010-10-15 18:22:41143 void RemoveEventListener(const std::string& event_name,
[email protected]f3b1a082011-11-18 00:34:30144 content::RenderProcessHost* process,
lazyboye7847242017-06-07 23:29:18145 const ExtensionId& extension_id);
146 void RemoveServiceWorkerEventListener(const std::string& event_name,
147 content::RenderProcessHost* process,
148 const ExtensionId& extension_id,
lazyboy63b994a2017-06-30 21:20:23149 const GURL& service_worker_scope,
Istiaque Ahmeda14ec482018-08-25 01:02:18150 int64_t service_worker_version_id,
lazyboye7847242017-06-07 23:29:18151 int worker_thread_id);
[email protected]2c699652010-10-15 18:22:41152
[email protected]c1abb3232014-07-30 18:28:39153 // Add or remove a URL as an event listener for |event_name|.
154 void AddEventListenerForURL(const std::string& event_name,
155 content::RenderProcessHost* process,
156 const GURL& listener_url);
157 void RemoveEventListenerForURL(const std::string& event_name,
158 content::RenderProcessHost* process,
159 const GURL& listener_url);
160
[email protected]f34706be2012-09-04 07:32:09161 EventListenerMap& listeners() { return listeners_; }
162
[email protected]c4dc5cc2012-11-09 08:48:39163 // Registers an observer to be notified when an event listener for
164 // |event_name| is added or removed. There can currently be only one observer
165 // for each distinct |event_name|.
thestig7ade5b52017-05-23 23:13:36166 void RegisterObserver(Observer* observer, const std::string& event_name);
[email protected]c4dc5cc2012-11-09 08:48:39167
168 // Unregisters an observer from all events.
169 void UnregisterObserver(Observer* observer);
170
Devlin Croninffbd2fe22018-07-20 17:20:17171 // Adds/removes test observers.
172 void AddObserverForTesting(TestObserver* observer);
173 void RemoveObserverForTesting(TestObserver* observer);
174
[email protected]36531222012-02-07 19:41:27175 // Add or remove the extension as having a lazy background page that listens
176 // to the event. The difference from the above methods is that these will be
177 // remembered even after the process goes away. We use this list to decide
178 // which extension pages to load when dispatching an event.
179 void AddLazyEventListener(const std::string& event_name,
lazyboye7847242017-06-07 23:29:18180 const ExtensionId& extension_id);
[email protected]36531222012-02-07 19:41:27181 void RemoveLazyEventListener(const std::string& event_name,
lazyboye7847242017-06-07 23:29:18182 const ExtensionId& extension_id);
183 // Similar to Add/RemoveLazyEventListener, but applies to extension service
184 // workers.
185 void AddLazyServiceWorkerEventListener(const std::string& event_name,
186 const ExtensionId& extension_id,
lazyboy63b994a2017-06-30 21:20:23187 const GURL& service_worker_scope);
lazyboye7847242017-06-07 23:29:18188 void RemoveLazyServiceWorkerEventListener(const std::string& event_name,
189 const ExtensionId& extension_id,
lazyboy63b994a2017-06-30 21:20:23190 const GURL& service_worker_scope);
[email protected]36531222012-02-07 19:41:27191
[email protected]d9e559d2012-07-05 01:04:57192 // If |add_lazy_listener| is true also add the lazy version of this listener.
Istiaque Ahmed9d1666182017-09-21 23:58:18193 void AddFilteredEventListener(
194 const std::string& event_name,
195 content::RenderProcessHost* process,
196 const std::string& extension_id,
197 base::Optional<ServiceWorkerIdentifier> sw_identifier,
198 const base::DictionaryValue& filter,
199 bool add_lazy_listener);
[email protected]d9e559d2012-07-05 01:04:57200
201 // If |remove_lazy_listener| is true also remove the lazy version of this
202 // listener.
Istiaque Ahmed9d1666182017-09-21 23:58:18203 void RemoveFilteredEventListener(
204 const std::string& event_name,
205 content::RenderProcessHost* process,
206 const std::string& extension_id,
207 base::Optional<ServiceWorkerIdentifier> sw_identifier,
208 const base::DictionaryValue& filter,
209 bool remove_lazy_listener);
[email protected]d9e559d2012-07-05 01:04:57210
[email protected]2c699652010-10-15 18:22:41211 // Returns true if there is at least one listener for the given event.
thestig7ade5b52017-05-23 23:13:36212 bool HasEventListener(const std::string& event_name) const;
[email protected]2c699652010-10-15 18:22:41213
[email protected]a7ab1b782010-10-21 23:24:16214 // Returns true if the extension is listening to the given event.
thestig7ade5b52017-05-23 23:13:36215 // (virtual for testing only.)
asargentd50b18c2016-04-21 01:17:16216 virtual bool ExtensionHasEventListener(const std::string& extension_id,
thestig7ade5b52017-05-23 23:13:36217 const std::string& event_name) const;
[email protected]a7ab1b782010-10-21 23:24:16218
[email protected]6e850922012-12-05 03:22:48219 // Broadcasts an event to every listener registered for that event.
dchengf5d241082016-04-21 03:43:11220 virtual void BroadcastEvent(std::unique_ptr<Event> event);
[email protected]6e850922012-12-05 03:22:48221
222 // Dispatches an event to the given extension.
223 virtual void DispatchEventToExtension(const std::string& extension_id,
dchengf5d241082016-04-21 03:43:11224 std::unique_ptr<Event> event);
[email protected]6e850922012-12-05 03:22:48225
[email protected]42d24742013-07-23 05:25:55226 // Dispatches |event| to the given extension as if the extension has a lazy
227 // listener for it. NOTE: This should be used rarely, for dispatching events
228 // to extensions that haven't had a chance to add their own listeners yet, eg:
229 // newly installed extensions.
230 void DispatchEventWithLazyListener(const std::string& extension_id,
dchengf5d241082016-04-21 03:43:11231 std::unique_ptr<Event> event);
[email protected]42d24742013-07-23 05:25:55232
[email protected]89102012011-11-01 21:23:56233 // Record the Event Ack from the renderer. (One less event in-flight.)
[email protected]45fd94172013-11-13 03:29:52234 void OnEventAck(content::BrowserContext* context,
David Bertoni3e1e9fa2018-08-29 20:39:30235 const std::string& extension_id,
236 const std::string& event_name);
[email protected]89102012011-11-01 21:23:56237
lazyboyac968912017-05-16 17:50:09238 // Returns whether or not the given extension has any registered events.
Istiaque Ahmed805f6a83b2017-10-05 01:23:26239 bool HasRegisteredEvents(const ExtensionId& extension_id) const;
lazyboyac968912017-05-16 17:50:09240
241 // Clears registered events for testing purposes.
lazyboye7847242017-06-07 23:29:18242 void ClearRegisteredEventsForTest(const ExtensionId& extension_id);
lazyboyac968912017-05-16 17:50:09243
kalmana9f6e67a2015-08-11 00:22:50244 // Reports UMA for an event dispatched to |extension| with histogram value
245 // |histogram_value|. Must be called on the UI thread.
246 //
247 // |did_enqueue| should be true if the event was queued waiting for a process
248 // to start, like an event page.
249 void ReportEvent(events::HistogramValue histogram_value,
250 const Extension* extension,
251 bool did_enqueue);
252
lazyboy75b9def2017-06-06 18:56:59253 LazyEventDispatchUtil* lazy_event_dispatch_util() {
254 return &lazy_event_dispatch_util_;
255 }
256
Istiaque Ahmeda14ec482018-08-25 01:02:18257 EventAckData* event_ack_data() { return &event_ack_data_; }
258
Devlin Cronin6e1ee262017-10-05 01:38:34259 // Returns true if there is a registered lazy/non-lazy listener for the given
rdevlin.cronin91f0c8a32017-07-19 21:26:33260 // |event_name|.
261 bool HasLazyEventListenerForTesting(const std::string& event_name);
Devlin Cronin6e1ee262017-10-05 01:38:34262 bool HasNonLazyEventListenerForTesting(const std::string& event_name);
rdevlin.cronin91f0c8a32017-07-19 21:26:33263
[email protected]fb6ff23b2012-03-13 23:13:42264 private:
lazyboy348e5ca2016-12-05 21:43:29265 friend class EventRouterFilterTest;
[email protected]c1abb3232014-07-30 18:28:39266 friend class EventRouterTest;
[email protected]c761a962013-11-20 04:19:41267
lazyboye7847242017-06-07 23:29:18268 enum class RegisteredEventType {
269 kLazy,
270 kServiceWorker,
271 };
272
[email protected]c9bd90f2012-08-07 23:58:15273 // TODO(gdk): Document this.
274 static void DispatchExtensionMessage(
275 IPC::Sender* ipc_sender,
lazyboye7847242017-06-07 23:29:18276 int worker_thread_id,
[email protected]513b8032013-11-18 07:47:49277 void* browser_context_id,
[email protected]c9bd90f2012-08-07 23:58:15278 const std::string& extension_id,
chirantan669993c2015-03-05 23:38:33279 int event_id,
[email protected]c9bd90f2012-08-07 23:58:15280 const std::string& event_name,
281 base::ListValue* event_args,
[email protected]c9bd90f2012-08-07 23:58:15282 UserGestureState user_gesture,
283 const extensions::EventFilteringInfo& info);
284
lazyboyac968912017-05-16 17:50:09285 // Returns or sets the list of events for which the given extension has
286 // registered.
lazyboye7847242017-06-07 23:29:18287 std::set<std::string> GetRegisteredEvents(const std::string& extension_id,
288 RegisteredEventType type) const;
lazyboyac968912017-05-16 17:50:09289 void SetRegisteredEvents(const std::string& extension_id,
lazyboye7847242017-06-07 23:29:18290 const std::set<std::string>& events,
291 RegisteredEventType type);
lazyboyac968912017-05-16 17:50:09292
[email protected]4243f9a2014-08-04 18:53:12293 // ExtensionRegistryObserver implementation.
dcheng9168b2f2014-10-21 12:38:24294 void OnExtensionLoaded(content::BrowserContext* browser_context,
295 const Extension* extension) override;
296 void OnExtensionUnloaded(content::BrowserContext* browser_context,
297 const Extension* extension,
limasdf0deef2042017-05-03 19:17:17298 UnloadedExtensionReason reason) override;
[email protected]2c699652010-10-15 18:22:41299
lazyboy63b994a2017-06-30 21:20:23300 void AddLazyEventListenerImpl(std::unique_ptr<EventListener> listener,
301 RegisteredEventType type);
302 void RemoveLazyEventListenerImpl(std::unique_ptr<EventListener> listener,
303 RegisteredEventType type);
lazyboye7847242017-06-07 23:29:18304
kalmana9f6e67a2015-08-11 00:22:50305 // Shared by all event dispatch methods. If |restrict_to_extension_id| is
306 // empty, the event is broadcast. An event that just came off the pending
307 // list may not be delayed again.
[email protected]d9e559d2012-07-05 01:04:57308 void DispatchEventImpl(const std::string& restrict_to_extension_id,
Devlin Cronin6db70572018-12-21 23:23:24309 std::unique_ptr<Event> event);
[email protected]fb6ff23b2012-03-13 23:13:42310
[email protected]c1abb3232014-07-30 18:28:39311 // Dispatches the event to the specified extension or URL running in
312 // |process|.
[email protected]d9e559d2012-07-05 01:04:57313 void DispatchEventToProcess(const std::string& extension_id,
[email protected]c1abb3232014-07-30 18:28:39314 const GURL& listener_url,
[email protected]d9e559d2012-07-05 01:04:57315 content::RenderProcessHost* process,
Istiaque Ahmeda14ec482018-08-25 01:02:18316 int64_t service_worker_version_id,
lazyboye7847242017-06-07 23:29:18317 int worker_thread_id,
Devlin Cronin6db70572018-12-21 23:23:24318 Event* event,
kalmana9f6e67a2015-08-11 00:22:50319 const base::DictionaryValue* listener_filter,
320 bool did_enqueue);
[email protected]fb6ff23b2012-03-13 23:13:42321
[email protected]e74d43c72013-05-17 19:01:41322 // Adds a filter to an event.
323 void AddFilterToEvent(const std::string& event_name,
324 const std::string& extension_id,
Istiaque Ahmed9ce21b32017-10-10 20:43:18325 bool is_for_service_worker,
[email protected]e74d43c72013-05-17 19:01:41326 const base::DictionaryValue* filter);
327
328 // Removes a filter from an event.
329 void RemoveFilterFromEvent(const std::string& event_name,
330 const std::string& extension_id,
Istiaque Ahmed9ce21b32017-10-10 20:43:18331 bool is_for_service_worker,
[email protected]e74d43c72013-05-17 19:01:41332 const base::DictionaryValue* filter);
333
334 // Returns the dictionary of event filters that the given extension has
335 // registered.
336 const base::DictionaryValue* GetFilteredEvents(
Istiaque Ahmed9ce21b32017-10-10 20:43:18337 const std::string& extension_id,
338 RegisteredEventType type);
[email protected]e74d43c72013-05-17 19:01:41339
chirantan669993c2015-03-05 23:38:33340 // Track the dispatched events that have not yet sent an ACK from the
341 // renderer.
[email protected]45fd94172013-11-13 03:29:52342 void IncrementInFlightEvents(content::BrowserContext* context,
David Bertonifc97d5ea2019-03-20 04:08:39343 content::RenderProcessHost* process,
chirantan669993c2015-03-05 23:38:33344 const Extension* extension,
345 int event_id,
David Bertonifc97d5ea2019-03-20 04:08:39346 const std::string& event_name,
347 int64_t service_worker_version_id);
[email protected]fb6ff23b2012-03-13 23:13:42348
[email protected]db9f2142013-05-27 22:56:16349 // static
kalmana9f6e67a2015-08-11 00:22:50350 static void DoDispatchEventToSenderBookkeepingOnUI(
351 void* browser_context_id,
David Bertonifc97d5ea2019-03-20 04:08:39352 int render_process_id,
kalmana9f6e67a2015-08-11 00:22:50353 const std::string& extension_id,
354 int event_id,
David Bertonifc97d5ea2019-03-20 04:08:39355 int64_t service_worker_version_id,
kalmana9f6e67a2015-08-11 00:22:50356 events::HistogramValue histogram_value,
357 const std::string& event_name);
[email protected]db9f2142013-05-27 22:56:16358
lazyboy63b994a2017-06-30 21:20:23359 void DispatchPendingEvent(
Devlin Cronin6db70572018-12-21 23:23:24360 std::unique_ptr<Event> event,
lazyboy63b994a2017-06-30 21:20:23361 std::unique_ptr<LazyContextTaskQueue::ContextInfo> params);
[email protected]fb6ff23b2012-03-13 23:13:42362
[email protected]5a38dfd2012-07-23 23:22:10363 // Implementation of EventListenerMap::Delegate.
dcheng9168b2f2014-10-21 12:38:24364 void OnListenerAdded(const EventListener* listener) override;
365 void OnListenerRemoved(const EventListener* listener) override;
[email protected]d9e559d2012-07-05 01:04:57366
amistry69e9ee422015-05-22 07:40:25367 // RenderProcessHostObserver implementation.
Bo Liu2a489402018-04-24 23:41:27368 void RenderProcessExited(
369 content::RenderProcessHost* host,
370 const content::ChildProcessTerminationInfo& info) override;
amistry69e9ee422015-05-22 07:40:25371 void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
372
thestig7ade5b52017-05-23 23:13:36373 content::BrowserContext* const browser_context_;
[email protected]45fd94172013-11-13 03:29:52374
[email protected]513b8032013-11-18 07:47:49375 // The ExtensionPrefs associated with |browser_context_|. May be NULL in
376 // tests.
thestig7ade5b52017-05-23 23:13:36377 ExtensionPrefs* const extension_prefs_;
[email protected]2c699652010-10-15 18:22:41378
[email protected]4243f9a2014-08-04 18:53:12379 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
380 extension_registry_observer_;
381
[email protected]d81d3a192012-11-09 00:32:50382 EventListenerMap listeners_;
[email protected]58c90952012-11-09 00:03:30383
[email protected]c761a962013-11-20 04:19:41384 // Map from base event name to observer.
thestig7ade5b52017-05-23 23:13:36385 using ObserverMap = std::unordered_map<std::string, Observer*>;
[email protected]c4dc5cc2012-11-09 08:48:39386 ObserverMap observers_;
387
Trent Apteda250ec3ab2018-08-19 08:52:19388 base::ObserverList<TestObserver>::Unchecked test_observers_;
Devlin Croninffbd2fe22018-07-20 17:20:17389
amistry69e9ee422015-05-22 07:40:25390 std::set<content::RenderProcessHost*> observed_process_set_;
391
lazyboy75b9def2017-06-06 18:56:59392 LazyEventDispatchUtil lazy_event_dispatch_util_;
393
Istiaque Ahmeda14ec482018-08-25 01:02:18394 EventAckData event_ack_data_;
395
lazyboye464732f2017-06-15 21:17:27396 base::WeakPtrFactory<EventRouter> weak_factory_;
397
[email protected]5a38dfd2012-07-23 23:22:10398 DISALLOW_COPY_AND_ASSIGN(EventRouter);
[email protected]2c699652010-10-15 18:22:41399};
400
[email protected]5a38dfd2012-07-23 23:22:10401struct Event {
reillyg5464e7e2014-12-11 00:35:08402 // This callback should return true if the event should be dispatched to the
403 // given context and extension, and false otherwise.
thestig7ade5b52017-05-23 23:13:36404 using WillDispatchCallback =
Devlin Cronin66bfdb82018-12-27 23:54:42405 base::RepeatingCallback<bool(content::BrowserContext*,
406 const Extension*,
407 Event*,
408 const base::DictionaryValue*)>;
[email protected]6e850922012-12-05 03:22:48409
kalmanf1b4d782015-06-24 21:14:05410 // The identifier for the event, for histograms. In most cases this
411 // correlates 1:1 with |event_name|, in some cases events will generate
412 // their own names, but they cannot generate their own identifier.
thestig7ade5b52017-05-23 23:13:36413 const events::HistogramValue histogram_value;
kalmanf1b4d782015-06-24 21:14:05414
[email protected]6e850922012-12-05 03:22:48415 // The event to dispatch.
thestig7ade5b52017-05-23 23:13:36416 const std::string event_name;
[email protected]6e850922012-12-05 03:22:48417
418 // Arguments to send to the event listener.
dchengf5d241082016-04-21 03:43:11419 std::unique_ptr<base::ListValue> event_args;
[email protected]6e850922012-12-05 03:22:48420
lazyboy59155a42017-05-24 22:23:35421 // If non-null, then the event will not be sent to other BrowserContexts
[email protected]45fd94172013-11-13 03:29:52422 // unless the extension has permission (e.g. incognito tab update -> normal
423 // tab only works if extension is allowed incognito access).
lazyboy59155a42017-05-24 22:23:35424 content::BrowserContext* const restrict_to_browser_context;
[email protected]6e850922012-12-05 03:22:48425
426 // If not empty, the event is only sent to extensions with host permissions
427 // for this url.
428 GURL event_url;
429
430 // Whether a user gesture triggered the event.
[email protected]5a38dfd2012-07-23 23:22:10431 EventRouter::UserGestureState user_gesture;
[email protected]6e850922012-12-05 03:22:48432
433 // Extra information used to filter which events are sent to the listener.
434 EventFilteringInfo filter_info;
435
436 // If specified, this is called before dispatching an event to each
437 // extension. The third argument is a mutable reference to event_args,
438 // allowing the caller to provide different arguments depending on the
439 // extension and profile. This is guaranteed to be called synchronously with
440 // DispatchEvent, so callers don't need to worry about lifetime.
[email protected]2c6e3b04c2014-07-24 12:48:09441 //
442 // NOTE: the Extension argument to this may be NULL because it's possible for
443 // this event to be dispatched to non-extension processes, like WebUI.
[email protected]6e850922012-12-05 03:22:48444 WillDispatchCallback will_dispatch_callback;
445
lazyboy59155a42017-05-24 22:23:35446 // TODO(lazyboy): This sets |restrict_to_browser_context| to nullptr, this
447 // will dispatch the event to unrelated profiles, not just incognito. Audit
448 // and limit usages of this constructor and introduce "include incognito"
449 // option to a constructor version for clients that need to disptach events to
450 // related browser_contexts. See https://crbug.com/726022.
kalmanf1b4d782015-06-24 21:14:05451 Event(events::HistogramValue histogram_value,
452 const std::string& event_name,
dchengf5d241082016-04-21 03:43:11453 std::unique_ptr<base::ListValue> event_args);
[email protected]d9e559d2012-07-05 01:04:57454
kalmanf1b4d782015-06-24 21:14:05455 Event(events::HistogramValue histogram_value,
456 const std::string& event_name,
dchengf5d241082016-04-21 03:43:11457 std::unique_ptr<base::ListValue> event_args,
[email protected]45fd94172013-11-13 03:29:52458 content::BrowserContext* restrict_to_browser_context);
[email protected]f0eb58a2012-12-17 22:10:49459
kalmanf1b4d782015-06-24 21:14:05460 Event(events::HistogramValue histogram_value,
461 const std::string& event_name,
dchengf5d241082016-04-21 03:43:11462 std::unique_ptr<base::ListValue> event_args,
[email protected]45fd94172013-11-13 03:29:52463 content::BrowserContext* restrict_to_browser_context,
[email protected]6e850922012-12-05 03:22:48464 const GURL& event_url,
[email protected]5a38dfd2012-07-23 23:22:10465 EventRouter::UserGestureState user_gesture,
466 const EventFilteringInfo& info);
[email protected]d9e559d2012-07-05 01:04:57467
[email protected]5a38dfd2012-07-23 23:22:10468 ~Event();
[email protected]6e850922012-12-05 03:22:48469
Devlin Cronin614b0142018-12-10 22:08:53470 // Makes a deep copy of this instance.
471 std::unique_ptr<Event> DeepCopy() const;
[email protected]d9e559d2012-07-05 01:04:57472};
473
[email protected]954e13492012-11-15 03:18:23474struct EventListenerInfo {
475 EventListenerInfo(const std::string& event_name,
[email protected]c761a962013-11-20 04:19:41476 const std::string& extension_id,
[email protected]c1abb3232014-07-30 18:28:39477 const GURL& listener_url,
[email protected]c761a962013-11-20 04:19:41478 content::BrowserContext* browser_context);
479 // The event name including any sub-event, e.g. "runtime.onStartup" or
480 // "webRequest.onCompleted/123".
[email protected]954e13492012-11-15 03:18:23481 const std::string event_name;
[email protected]c761a962013-11-20 04:19:41482
[email protected]954e13492012-11-15 03:18:23483 const std::string extension_id;
[email protected]c1abb3232014-07-30 18:28:39484 const GURL listener_url;
thestig7ade5b52017-05-23 23:13:36485 content::BrowserContext* const browser_context;
[email protected]954e13492012-11-15 03:18:23486};
487
[email protected]5a38dfd2012-07-23 23:22:10488} // namespace extensions
[email protected]d9e559d2012-07-05 01:04:57489
[email protected]34423532013-11-21 18:13:10490#endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_