blob: bbb3e22d4858e9803d1621496229333ff83acc4a [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
5#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_
6#define CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_
7#pragma once
8
9#include <map>
10#include <set>
11#include <string>
12
[email protected]17902752011-08-31 22:52:5413#include "base/compiler_specific.h"
[email protected]f72d0c62011-08-31 16:27:4414#include "base/memory/linked_ptr.h"
[email protected]3b63f8f42011-03-28 01:54:1515#include "base/memory/ref_counted.h"
[email protected]6c2381d2011-10-19 02:52:5316#include "content/public/browser/notification_observer.h"
17#include "content/public/browser/notification_registrar.h"
[email protected]b44f8ad2012-06-15 20:52:5818#include "ipc/ipc_sender.h"
[email protected]2c699652010-10-15 18:22:4119
20class GURL;
[email protected]b6536df2012-03-16 18:55:2321class ExtensionHost;
[email protected]2c699652010-10-15 18:22:4122class ExtensionDevToolsManager;
23class Profile;
[email protected]f3b1a082011-11-18 00:34:3024
25namespace content {
[email protected]2c699652010-10-15 18:22:4126class RenderProcessHost;
[email protected]f3b1a082011-11-18 00:34:3027}
[email protected]2c699652010-10-15 18:22:4128
[email protected]1c321ee52012-05-21 03:02:3429namespace extensions {
30class Extension;
31}
32
[email protected]6c2381d2011-10-19 02:52:5333class ExtensionEventRouter : public content::NotificationObserver {
[email protected]2c699652010-10-15 18:22:4134 public:
[email protected]b085856f2012-03-02 04:37:2535 // These constants convey the state of our knowledge of whether we're in
36 // a user-caused gesture as part of DispatchEvent.
37 enum UserGestureState {
38 USER_GESTURE_UNKNOWN = 0,
39 USER_GESTURE_ENABLED = 1,
40 USER_GESTURE_NOT_ENABLED = 2,
41 };
42
[email protected]c357acb42011-06-09 20:52:4243 // Sends an event via ipc_sender to the given extension. Can be called on
44 // any thread.
[email protected]b44f8ad2012-06-15 20:52:5845 static void DispatchEvent(IPC::Sender* ipc_sender,
[email protected]c357acb42011-06-09 20:52:4246 const std::string& extension_id,
47 const std::string& event_name,
48 const std::string& event_args,
[email protected]b085856f2012-03-02 04:37:2549 const GURL& event_url,
50 UserGestureState user_gesture);
[email protected]5a7b5eaf2010-11-02 20:52:1951
[email protected]2c699652010-10-15 18:22:4152 explicit ExtensionEventRouter(Profile* profile);
[email protected]3690ebe02011-05-25 09:08:1953 virtual ~ExtensionEventRouter();
[email protected]2c699652010-10-15 18:22:4154
[email protected]a7ab1b782010-10-21 23:24:1655 // Add or remove the process/extension pair as a listener for |event_name|.
56 // Note that multiple extensions can share a process due to process
57 // collapsing. Also, a single extension can have 2 processes if it is a split
58 // mode extension.
[email protected]2c699652010-10-15 18:22:4159 void AddEventListener(const std::string& event_name,
[email protected]f3b1a082011-11-18 00:34:3060 content::RenderProcessHost* process,
[email protected]a7ab1b782010-10-21 23:24:1661 const std::string& extension_id);
[email protected]2c699652010-10-15 18:22:4162 void RemoveEventListener(const std::string& event_name,
[email protected]f3b1a082011-11-18 00:34:3063 content::RenderProcessHost* process,
[email protected]a7ab1b782010-10-21 23:24:1664 const std::string& extension_id);
[email protected]2c699652010-10-15 18:22:4165
[email protected]36531222012-02-07 19:41:2766 // Add or remove the extension as having a lazy background page that listens
67 // to the event. The difference from the above methods is that these will be
68 // remembered even after the process goes away. We use this list to decide
69 // which extension pages to load when dispatching an event.
70 void AddLazyEventListener(const std::string& event_name,
71 const std::string& extension_id);
72 void RemoveLazyEventListener(const std::string& event_name,
73 const std::string& extension_id);
74
[email protected]2c699652010-10-15 18:22:4175 // Returns true if there is at least one listener for the given event.
76 bool HasEventListener(const std::string& event_name);
77
[email protected]a7ab1b782010-10-21 23:24:1678 // Returns true if the extension is listening to the given event.
79 bool ExtensionHasEventListener(const std::string& extension_id,
80 const std::string& event_name);
81
[email protected]2c699652010-10-15 18:22:4182 // Send an event to every registered extension renderer. If
83 // |restrict_to_profile| is non-NULL, then the event will not be sent to other
84 // profiles unless the extension has permission (e.g. incognito tab update ->
85 // normal profile only works if extension is allowed incognito access). If
86 // |event_url| is not empty, the event is only sent to extension with host
87 // permissions for this url.
[email protected]a7ab1b782010-10-21 23:24:1688 void DispatchEventToRenderers(
[email protected]0a184b52011-06-23 00:41:1389 const std::string& event_name,
90 const std::string& event_args,
91 Profile* restrict_to_profile,
92 const GURL& event_url);
[email protected]2c699652010-10-15 18:22:4193
[email protected]a7ab1b782010-10-21 23:24:1694 // Same as above, except only send the event to the given extension.
[email protected]f72d0c62011-08-31 16:27:4495 virtual void DispatchEventToExtension(
[email protected]2c699652010-10-15 18:22:4196 const std::string& extension_id,
[email protected]0a184b52011-06-23 00:41:1397 const std::string& event_name,
98 const std::string& event_args,
99 Profile* restrict_to_profile,
100 const GURL& event_url);
101
[email protected]b085856f2012-03-02 04:37:25102 // Dispatch an event to particular extension. Also include an
103 // explicit user gesture indicator.
104 virtual void DispatchEventToExtension(
105 const std::string& extension_id,
106 const std::string& event_name,
107 const std::string& event_args,
108 Profile* restrict_to_profile,
109 const GURL& event_url,
110 UserGestureState user_gesture);
111
[email protected]0a184b52011-06-23 00:41:13112 // Send different versions of an event to extensions in different profiles.
113 // This is used in the case of sending one event to extensions that have
114 // incognito access, and another event to extensions that don't (here),
115 // in order to avoid sending 2 events to "spanning" extensions.
116 // If |cross_incognito_profile| is non-NULL and different from
117 // restrict_to_profile, send the event with cross_incognito_args to the
118 // extensions in that profile that can't cross incognito.
119 void DispatchEventsToRenderersAcrossIncognito(
120 const std::string& event_name,
121 const std::string& event_args,
122 Profile* restrict_to_profile,
123 const std::string& cross_incognito_args,
124 const GURL& event_url);
[email protected]2c699652010-10-15 18:22:41125
[email protected]89102012011-11-01 21:23:56126 // Record the Event Ack from the renderer. (One less event in-flight.)
[email protected]7042b682012-04-19 22:57:51127 void OnEventAck(Profile* profile, const std::string& extension_id);
[email protected]89102012011-11-01 21:23:56128
[email protected]fb6ff23b2012-03-13 23:13:42129 private:
[email protected]f72d0c62011-08-31 16:27:44130 // The details of an event to be dispatched.
131 struct ExtensionEvent;
132
[email protected]61f5fc82012-02-15 20:10:45133 // The extension and process that contains the event listener for a given
134 // event.
135 struct ListenerProcess;
136
137 // A map between an event name and a set of extensions that are listening
138 // to that event.
139 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap;
[email protected]a7ab1b782010-10-21 23:24:16140
[email protected]432115822011-07-10 15:52:27141 virtual void Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53142 const content::NotificationSource& source,
143 const content::NotificationDetails& details) OVERRIDE;
[email protected]2c699652010-10-15 18:22:41144
[email protected]61f5fc82012-02-15 20:10:45145 // Returns true if the given listener map contains a event listeners for
146 // the given event. If |extension_id| is non-empty, we also check that that
147 // extension is one of the listeners.
148 bool HasEventListenerImpl(const ListenerMap& listeners,
149 const std::string& extension_id,
150 const std::string& event_name);
151
[email protected]fb6ff23b2012-03-13 23:13:42152 // Shared by DispatchEvent*. If |extension_id| is empty, the event is
153 // broadcast. If |process| is non-NULL, the event is only dispatched to that
154 // particular process.
155 // An event that just came off the pending list may not be delayed again.
156 void DispatchEventImpl(const std::string& extension_id,
157 const linked_ptr<ExtensionEvent>& event);
158
159 // Dispatches the event to a single listener process.
160 void DispatchEventToListener(const ListenerProcess& listener,
161 const linked_ptr<ExtensionEvent>& event);
162
163 // Returns false when the event is scoped to a profile and the listening
164 // extension does not have access to events from that profile. Also fills
165 // |event_args| with the proper arguments to send, which may differ if
166 // the event crosses the incognito boundary.
167 bool CanDispatchEventToProfile(
168 Profile* profile,
[email protected]1c321ee52012-05-21 03:02:34169 const extensions::Extension* extension,
[email protected]fb6ff23b2012-03-13 23:13:42170 const linked_ptr<ExtensionEvent>& event,
171 const std::string** event_args);
172
173 // Ensures that all lazy background pages that are interested in the given
174 // event are loaded, and queues the event if the page is not ready yet.
175 // If |extension_id| is non-empty, we load only that extension's page
176 // (assuming it is interested in the event).
177 void LoadLazyBackgroundPagesForEvent(
178 const std::string& extension_id,
179 const linked_ptr<ExtensionEvent>& event);
180
181 // Possibly loads given extension's background page in preparation to
182 // dispatch an event.
183 void MaybeLoadLazyBackgroundPage(
184 Profile* profile,
[email protected]1c321ee52012-05-21 03:02:34185 const extensions::Extension* extension,
[email protected]fb6ff23b2012-03-13 23:13:42186 const linked_ptr<ExtensionEvent>& event);
187
[email protected]fb6ff23b2012-03-13 23:13:42188 // Track of the number of dispatched events that have not yet sent an
189 // ACK from the renderer.
[email protected]1c321ee52012-05-21 03:02:34190 void IncrementInFlightEvents(Profile* profile,
191 const extensions::Extension* extension);
[email protected]fb6ff23b2012-03-13 23:13:42192
[email protected]b6536df2012-03-16 18:55:23193 void DispatchPendingEvent(const linked_ptr<ExtensionEvent>& event,
194 ExtensionHost* host);
[email protected]fb6ff23b2012-03-13 23:13:42195
[email protected]2c699652010-10-15 18:22:41196 Profile* profile_;
197
[email protected]6c2381d2011-10-19 02:52:53198 content::NotificationRegistrar registrar_;
[email protected]2c699652010-10-15 18:22:41199
200 scoped_refptr<ExtensionDevToolsManager> extension_devtools_manager_;
201
[email protected]61f5fc82012-02-15 20:10:45202 // The list of active extension processes that are listening to events.
[email protected]2c699652010-10-15 18:22:41203 ListenerMap listeners_;
204
[email protected]61f5fc82012-02-15 20:10:45205 // The list of all the lazy (non-persistent) background pages that are
206 // listening to events. This is just a cache of the real list, which is
207 // stored on disk in the extension prefs.
[email protected]36531222012-02-07 19:41:27208 ListenerMap lazy_listeners_;
209
[email protected]2c699652010-10-15 18:22:41210 DISALLOW_COPY_AND_ASSIGN(ExtensionEventRouter);
211};
212
213#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_