Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: extensions/browser/event_router.cc

Issue 2886923002: [extension SW]: Support event listener registration and event dispatching. (Closed)
Patch Set: sync Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « extensions/browser/event_router.h ('k') | extensions/browser/extension_message_filter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/event_router.h" 5 #include "extensions/browser/event_router.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 BrowserContext* context = static_cast<BrowserContext*>(browser_context_id); 61 BrowserContext* context = static_cast<BrowserContext*>(browser_context_id);
62 activity_monitor::OnApiEventDispatched(context, extension_id, event_name, 62 activity_monitor::OnApiEventDispatched(context, extension_id, event_name,
63 args); 63 args);
64 } 64 }
65 65
66 // A global identifier used to distinguish extension events. 66 // A global identifier used to distinguish extension events.
67 base::StaticAtomicSequenceNumber g_extension_event_id; 67 base::StaticAtomicSequenceNumber g_extension_event_id;
68 68
69 } // namespace 69 } // namespace
70 70
71 const char EventRouter::kRegisteredEvents[] = "events"; 71 const char EventRouter::kRegisteredLazyEvents[] = "events";
72 const char EventRouter::kRegisteredServiceWorkerEvents[] =
73 "serviceworkerevents";
72 74
73 // static 75 // static
74 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, 76 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender,
77 int worker_thread_id,
75 void* browser_context_id, 78 void* browser_context_id,
76 const std::string& extension_id, 79 const std::string& extension_id,
77 int event_id, 80 int event_id,
78 const std::string& event_name, 81 const std::string& event_name,
79 ListValue* event_args, 82 ListValue* event_args,
80 UserGestureState user_gesture, 83 UserGestureState user_gesture,
81 const EventFilteringInfo& info) { 84 const EventFilteringInfo& info) {
82 NotifyEventDispatched(browser_context_id, extension_id, event_name, 85 NotifyEventDispatched(browser_context_id, extension_id, event_name,
83 *event_args); 86 *event_args);
84 87
85 ExtensionMsg_DispatchEvent_Params params; 88 ExtensionMsg_DispatchEvent_Params params;
89 params.worker_thread_id = worker_thread_id;
86 params.extension_id = extension_id; 90 params.extension_id = extension_id;
87 params.event_name = event_name; 91 params.event_name = event_name;
88 params.event_id = event_id; 92 params.event_id = event_id;
89 params.is_user_gesture = user_gesture == USER_GESTURE_ENABLED; 93 params.is_user_gesture = user_gesture == USER_GESTURE_ENABLED;
90 params.filtering_info.Swap(info.AsValue().get()); 94 params.filtering_info.Swap(info.AsValue().get());
91 95
92 ipc_sender->Send(new ExtensionMsg_DispatchEvent(params, *event_args)); 96 ipc_sender->Send(new ExtensionMsg_DispatchEvent(params, *event_args));
93 } 97 }
94 98
95 // static 99 // static
(...skipping 25 matching lines...) Expand all
121 } else { 125 } else {
122 // This is called from WebRequest API. 126 // This is called from WebRequest API.
123 // TODO(lazyboy): Skip this entirely: http://crbug.com/488747. 127 // TODO(lazyboy): Skip this entirely: http://crbug.com/488747.
124 BrowserThread::PostTask( 128 BrowserThread::PostTask(
125 BrowserThread::UI, FROM_HERE, 129 BrowserThread::UI, FROM_HERE,
126 base::Bind(&EventRouter::DoDispatchEventToSenderBookkeepingOnUI, 130 base::Bind(&EventRouter::DoDispatchEventToSenderBookkeepingOnUI,
127 browser_context_id, extension_id, event_id, histogram_value, 131 browser_context_id, extension_id, event_id, histogram_value,
128 event_name)); 132 event_name));
129 } 133 }
130 134
131 DispatchExtensionMessage(ipc_sender, browser_context_id, extension_id, 135 DispatchExtensionMessage(ipc_sender,
136 // TODO(lazyboy): |kNonWorkerThreadId| means these
137 // will not work for extension SW.
138 kNonWorkerThreadId, browser_context_id, extension_id,
132 event_id, event_name, event_args.get(), user_gesture, 139 event_id, event_name, event_args.get(), user_gesture,
133 info); 140 info);
134 } 141 }
135 142
136 EventRouter::EventRouter(BrowserContext* browser_context, 143 EventRouter::EventRouter(BrowserContext* browser_context,
137 ExtensionPrefs* extension_prefs) 144 ExtensionPrefs* extension_prefs)
138 : browser_context_(browser_context), 145 : browser_context_(browser_context),
139 extension_prefs_(extension_prefs), 146 extension_prefs_(extension_prefs),
140 extension_registry_observer_(this), 147 extension_registry_observer_(this),
141 listeners_(this), 148 listeners_(this),
142 lazy_event_dispatch_util_(browser_context_) { 149 lazy_event_dispatch_util_(browser_context_) {
143 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); 150 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
144 } 151 }
145 152
146 EventRouter::~EventRouter() { 153 EventRouter::~EventRouter() {
147 for (auto* process : observed_process_set_) 154 for (auto* process : observed_process_set_)
148 process->RemoveObserver(this); 155 process->RemoveObserver(this);
149 } 156 }
150 157
151 void EventRouter::AddEventListener(const std::string& event_name, 158 void EventRouter::AddEventListener(const std::string& event_name,
152 content::RenderProcessHost* process, 159 content::RenderProcessHost* process,
153 const std::string& extension_id) { 160 const std::string& extension_id) {
154 listeners_.AddListener(EventListener::ForExtension( 161 listeners_.AddListener(
155 event_name, extension_id, process, std::unique_ptr<DictionaryValue>())); 162 EventListener::ForExtension(event_name, extension_id, process, nullptr));
163 }
164
165 void EventRouter::AddServiceWorkerEventListener(
166 const std::string& event_name,
167 content::RenderProcessHost* process,
168 const ExtensionId& extension_id,
169 int worker_thread_id) {
170 listeners_.AddListener(EventListener::ForExtensionServiceWorker(
171 event_name, extension_id, process, worker_thread_id, nullptr));
156 } 172 }
157 173
158 void EventRouter::RemoveEventListener(const std::string& event_name, 174 void EventRouter::RemoveEventListener(const std::string& event_name,
159 content::RenderProcessHost* process, 175 content::RenderProcessHost* process,
160 const std::string& extension_id) { 176 const std::string& extension_id) {
161 std::unique_ptr<EventListener> listener = EventListener::ForExtension( 177 std::unique_ptr<EventListener> listener =
162 event_name, extension_id, process, std::unique_ptr<DictionaryValue>()); 178 EventListener::ForExtension(event_name, extension_id, process, nullptr);
179 listeners_.RemoveListener(listener.get());
180 }
181
182 void EventRouter::RemoveServiceWorkerEventListener(
183 const std::string& event_name,
184 content::RenderProcessHost* process,
185 const ExtensionId& extension_id,
186 int worker_thread_id) {
187 std::unique_ptr<EventListener> listener =
188 EventListener::ForExtensionServiceWorker(
189 event_name, extension_id, process, worker_thread_id, nullptr);
163 listeners_.RemoveListener(listener.get()); 190 listeners_.RemoveListener(listener.get());
164 } 191 }
165 192
166 void EventRouter::AddEventListenerForURL(const std::string& event_name, 193 void EventRouter::AddEventListenerForURL(const std::string& event_name,
167 content::RenderProcessHost* process, 194 content::RenderProcessHost* process,
168 const GURL& listener_url) { 195 const GURL& listener_url) {
169 listeners_.AddListener(EventListener::ForURL( 196 listeners_.AddListener(
170 event_name, listener_url, process, std::unique_ptr<DictionaryValue>())); 197 EventListener::ForURL(event_name, listener_url, process, nullptr));
171 } 198 }
172 199
173 void EventRouter::RemoveEventListenerForURL(const std::string& event_name, 200 void EventRouter::RemoveEventListenerForURL(const std::string& event_name,
174 content::RenderProcessHost* process, 201 content::RenderProcessHost* process,
175 const GURL& listener_url) { 202 const GURL& listener_url) {
176 std::unique_ptr<EventListener> listener = EventListener::ForURL( 203 std::unique_ptr<EventListener> listener =
177 event_name, listener_url, process, std::unique_ptr<DictionaryValue>()); 204 EventListener::ForURL(event_name, listener_url, process, nullptr);
178 listeners_.RemoveListener(listener.get()); 205 listeners_.RemoveListener(listener.get());
179 } 206 }
180 207
181 void EventRouter::RegisterObserver(Observer* observer, 208 void EventRouter::RegisterObserver(Observer* observer,
182 const std::string& event_name) { 209 const std::string& event_name) {
183 // Observing sub-event names like "foo.onBar/123" is not allowed. 210 // Observing sub-event names like "foo.onBar/123" is not allowed.
184 DCHECK(event_name.find('/') == std::string::npos); 211 DCHECK(event_name.find('/') == std::string::npos);
185 observers_[event_name] = observer; 212 observers_[event_name] = observer;
186 } 213 }
187 214
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 host->RemoveObserver(this); 258 host->RemoveObserver(this);
232 } 259 }
233 260
234 void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) { 261 void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) {
235 listeners_.RemoveListenersForProcess(host); 262 listeners_.RemoveListenersForProcess(host);
236 observed_process_set_.erase(host); 263 observed_process_set_.erase(host);
237 host->RemoveObserver(this); 264 host->RemoveObserver(this);
238 } 265 }
239 266
240 void EventRouter::AddLazyEventListener(const std::string& event_name, 267 void EventRouter::AddLazyEventListener(const std::string& event_name,
241 const std::string& extension_id) { 268 const ExtensionId& extension_id) {
242 bool is_new = listeners_.AddListener(EventListener::ForExtension( 269 AddLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId);
243 event_name, extension_id, NULL, std::unique_ptr<DictionaryValue>()));
244
245 if (is_new) {
246 std::set<std::string> events = GetRegisteredEvents(extension_id);
247 bool prefs_is_new = events.insert(event_name).second;
248 if (prefs_is_new)
249 SetRegisteredEvents(extension_id, events);
250 }
251 } 270 }
252 271
253 void EventRouter::RemoveLazyEventListener(const std::string& event_name, 272 void EventRouter::RemoveLazyEventListener(const std::string& event_name,
254 const std::string& extension_id) { 273 const ExtensionId& extension_id) {
255 std::unique_ptr<EventListener> listener = EventListener::ForExtension( 274 RemoveLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId);
256 event_name, extension_id, NULL, std::unique_ptr<DictionaryValue>());
257 bool did_exist = listeners_.RemoveListener(listener.get());
258
259 if (did_exist) {
260 std::set<std::string> events = GetRegisteredEvents(extension_id);
261 bool prefs_did_exist = events.erase(event_name) > 0;
262 DCHECK(prefs_did_exist);
263 SetRegisteredEvents(extension_id, events);
264 }
265 } 275 }
266 276
277 void EventRouter::AddLazyServiceWorkerEventListener(
278 const std::string& event_name,
279 const ExtensionId& extension_id,
280 int worker_thread_id) {
281 AddLazyEventListenerImpl(event_name, extension_id, worker_thread_id);
282 }
283
284 void EventRouter::RemoveLazyServiceWorkerEventListener(
285 const std::string& event_name,
286 const ExtensionId& extension_id,
287 int worker_thread_id) {
288 RemoveLazyEventListenerImpl(event_name, extension_id, worker_thread_id);
289 }
290
291 // TODO(lazyboy): Support filters for extension SW events.
267 void EventRouter::AddFilteredEventListener(const std::string& event_name, 292 void EventRouter::AddFilteredEventListener(const std::string& event_name,
268 content::RenderProcessHost* process, 293 content::RenderProcessHost* process,
269 const std::string& extension_id, 294 const std::string& extension_id,
270 const base::DictionaryValue& filter, 295 const base::DictionaryValue& filter,
271 bool add_lazy_listener) { 296 bool add_lazy_listener) {
272 listeners_.AddListener(EventListener::ForExtension( 297 listeners_.AddListener(EventListener::ForExtension(
273 event_name, extension_id, process, 298 event_name, extension_id, process,
274 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); 299 std::unique_ptr<DictionaryValue>(filter.DeepCopy())));
275 300
276 if (!add_lazy_listener) 301 if (!add_lazy_listener)
277 return; 302 return;
278 303
279 bool added = listeners_.AddListener(EventListener::ForExtension( 304 bool added = listeners_.AddListener(EventListener::ForExtension(
280 event_name, extension_id, nullptr, 305 event_name, extension_id, nullptr,
281 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); 306 std::unique_ptr<DictionaryValue>(filter.DeepCopy())));
282 if (added) 307 if (added)
283 AddFilterToEvent(event_name, extension_id, &filter); 308 AddFilterToEvent(event_name, extension_id, &filter);
284 } 309 }
285 310
311 // TODO(lazyboy): Support filters for extension SW events.
286 void EventRouter::RemoveFilteredEventListener( 312 void EventRouter::RemoveFilteredEventListener(
287 const std::string& event_name, 313 const std::string& event_name,
288 content::RenderProcessHost* process, 314 content::RenderProcessHost* process,
289 const std::string& extension_id, 315 const std::string& extension_id,
290 const base::DictionaryValue& filter, 316 const base::DictionaryValue& filter,
291 bool remove_lazy_listener) { 317 bool remove_lazy_listener) {
292 std::unique_ptr<EventListener> listener = EventListener::ForExtension( 318 std::unique_ptr<EventListener> listener = EventListener::ForExtension(
293 event_name, extension_id, process, 319 event_name, extension_id, process,
294 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); 320 std::unique_ptr<DictionaryValue>(filter.DeepCopy()));
295 321
(...skipping 12 matching lines...) Expand all
308 return listeners_.HasListenerForEvent(event_name); 334 return listeners_.HasListenerForEvent(event_name);
309 } 335 }
310 336
311 bool EventRouter::ExtensionHasEventListener( 337 bool EventRouter::ExtensionHasEventListener(
312 const std::string& extension_id, 338 const std::string& extension_id,
313 const std::string& event_name) const { 339 const std::string& event_name) const {
314 return listeners_.HasListenerForExtension(extension_id, event_name); 340 return listeners_.HasListenerForExtension(extension_id, event_name);
315 } 341 }
316 342
317 std::set<std::string> EventRouter::GetRegisteredEvents( 343 std::set<std::string> EventRouter::GetRegisteredEvents(
318 const std::string& extension_id) const { 344 const std::string& extension_id,
345 RegisteredEventType type) const {
319 std::set<std::string> events; 346 std::set<std::string> events;
320 const ListValue* events_value = NULL; 347 const ListValue* events_value = NULL;
321 348
322 if (!extension_prefs_ || 349 const char* pref_key = type == RegisteredEventType::kLazy
323 !extension_prefs_->ReadPrefAsList( 350 ? kRegisteredLazyEvents
324 extension_id, kRegisteredEvents, &events_value)) { 351 : kRegisteredServiceWorkerEvents;
352 if (!extension_prefs_ || !extension_prefs_->ReadPrefAsList(
353 extension_id, pref_key, &events_value)) {
325 return events; 354 return events;
326 } 355 }
327 356
328 for (size_t i = 0; i < events_value->GetSize(); ++i) { 357 for (size_t i = 0; i < events_value->GetSize(); ++i) {
329 std::string event; 358 std::string event;
330 if (events_value->GetString(i, &event)) 359 if (events_value->GetString(i, &event))
331 events.insert(event); 360 events.insert(event);
332 } 361 }
333 return events; 362 return events;
334 } 363 }
335 364
365 void EventRouter::ClearRegisteredEventsForTest(
366 const ExtensionId& extension_id) {
367 SetRegisteredEvents(extension_id, std::set<std::string>(),
368 RegisteredEventType::kLazy);
369 SetRegisteredEvents(extension_id, std::set<std::string>(),
370 RegisteredEventType::kServiceWorker);
371 }
372
336 void EventRouter::RemoveFilterFromEvent(const std::string& event_name, 373 void EventRouter::RemoveFilterFromEvent(const std::string& event_name,
337 const std::string& extension_id, 374 const std::string& extension_id,
338 const DictionaryValue* filter) { 375 const DictionaryValue* filter) {
339 ExtensionPrefs::ScopedDictionaryUpdate update( 376 ExtensionPrefs::ScopedDictionaryUpdate update(
340 extension_prefs_, extension_id, kFilteredEvents); 377 extension_prefs_, extension_id, kFilteredEvents);
341 auto filtered_events = update.Create(); 378 auto filtered_events = update.Create();
342 ListValue* filter_list = NULL; 379 ListValue* filter_list = NULL;
343 if (!filtered_events || 380 if (!filtered_events ||
344 !filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { 381 !filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) {
345 return; 382 return;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 if (!has_listener) 421 if (!has_listener)
385 RemoveLazyEventListener(event_name, extension_id); 422 RemoveLazyEventListener(event_name, extension_id);
386 } 423 }
387 424
388 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, 425 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id,
389 const linked_ptr<Event>& event) { 426 const linked_ptr<Event>& event) {
390 // We don't expect to get events from a completely different browser context. 427 // We don't expect to get events from a completely different browser context.
391 DCHECK(!event->restrict_to_browser_context || 428 DCHECK(!event->restrict_to_browser_context ||
392 ExtensionsBrowserClient::Get()->IsSameContext( 429 ExtensionsBrowserClient::Get()->IsSameContext(
393 browser_context_, event->restrict_to_browser_context)); 430 browser_context_, event->restrict_to_browser_context));
394
395 std::set<const EventListener*> listeners( 431 std::set<const EventListener*> listeners(
396 listeners_.GetEventListeners(*event)); 432 listeners_.GetEventListeners(*event));
397 433
398 std::set<EventDispatchIdentifier> already_dispatched; 434 std::set<EventDispatchIdentifier> already_dispatched;
399 435
400 // We dispatch events for lazy background pages first because attempting to do 436 // We dispatch events for lazy background pages first because attempting to do
401 // so will cause those that are being suspended to cancel that suspension. 437 // so will cause those that are being suspended to cancel that suspension.
402 // As canceling a suspension entails sending an event to the affected 438 // As canceling a suspension entails sending an event to the affected
403 // background page, and as that event needs to be delivered before we dispatch 439 // background page, and as that event needs to be delivered before we dispatch
404 // the event we are dispatching here, we dispatch to the lazy listeners here 440 // the event we are dispatching here, we dispatch to the lazy listeners here
405 // first. 441 // first.
406 for (const EventListener* listener : listeners) { 442 for (const EventListener* listener : listeners) {
407 if (restrict_to_extension_id.empty() || 443 if (restrict_to_extension_id.empty() ||
408 restrict_to_extension_id == listener->extension_id()) { 444 restrict_to_extension_id == listener->extension_id()) {
409 if (listener->IsLazy()) { 445 // TODO(lazyboy): Support lazy listeners for extension SW events.
446 if (listener->IsLazy() && !listener->IsForServiceWorker()) {
410 DispatchLazyEvent(listener->extension_id(), event, &already_dispatched, 447 DispatchLazyEvent(listener->extension_id(), event, &already_dispatched,
411 listener->filter()); 448 listener->filter());
412 } 449 }
413 } 450 }
414 } 451 }
415 452
416 for (const EventListener* listener : listeners) { 453 for (const EventListener* listener : listeners) {
417 if (restrict_to_extension_id.empty() || 454 if (restrict_to_extension_id.empty() ||
418 restrict_to_extension_id == listener->extension_id()) { 455 restrict_to_extension_id == listener->extension_id()) {
419 if (listener->process()) { 456 if (listener->process()) {
420 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), 457 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(),
421 listener->extension_id()); 458 listener->extension_id(),
459 listener->worker_thread_id());
422 if (!base::ContainsKey(already_dispatched, dispatch_id)) { 460 if (!base::ContainsKey(already_dispatched, dispatch_id)) {
423 DispatchEventToProcess(listener->extension_id(), 461 DispatchEventToProcess(listener->extension_id(),
424 listener->listener_url(), listener->process(), 462 listener->listener_url(), listener->process(),
425 event, listener->filter(), 463 listener->worker_thread_id(), event,
426 false /* did_enqueue */); 464 listener->filter(), false /* did_enqueue */);
427 } 465 }
428 } 466 }
429 } 467 }
430 } 468 }
431 } 469 }
432 470
433 void EventRouter::DispatchLazyEvent( 471 void EventRouter::DispatchLazyEvent(
434 const std::string& extension_id, 472 const std::string& extension_id,
435 const linked_ptr<Event>& event, 473 const linked_ptr<Event>& event,
436 std::set<EventDispatchIdentifier>* already_dispatched, 474 std::set<EventDispatchIdentifier>* already_dispatched,
437 const base::DictionaryValue* listener_filter) { 475 const base::DictionaryValue* listener_filter) {
438 // Check both the original and the incognito browser context to see if we 476 // Check both the original and the incognito browser context to see if we
439 // should load a lazy bg page to handle the event. The latter case 477 // should load a lazy bg page to handle the event. The latter case
440 // occurs in the case of split-mode extensions. 478 // occurs in the case of split-mode extensions.
441 const Extension* extension = 479 const Extension* extension =
442 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( 480 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID(
443 extension_id); 481 extension_id);
444 if (!extension) 482 if (!extension)
445 return; 483 return;
446 484
447 if (MaybeLoadLazyBackgroundPageToDispatchEvent(browser_context_, extension, 485 if (MaybeLoadLazyBackgroundPageToDispatchEvent(browser_context_, extension,
448 event, listener_filter)) { 486 event, listener_filter)) {
449 already_dispatched->insert(std::make_pair(browser_context_, extension_id)); 487 already_dispatched->insert(
488 std::make_tuple(browser_context_, extension_id, kNonWorkerThreadId));
450 } 489 }
451 490
452 ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get(); 491 ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get();
453 if (browser_client->HasOffTheRecordContext(browser_context_) && 492 if (browser_client->HasOffTheRecordContext(browser_context_) &&
454 IncognitoInfo::IsSplitMode(extension)) { 493 IncognitoInfo::IsSplitMode(extension)) {
455 BrowserContext* incognito_context = 494 BrowserContext* incognito_context =
456 browser_client->GetOffTheRecordContext(browser_context_); 495 browser_client->GetOffTheRecordContext(browser_context_);
457 if (MaybeLoadLazyBackgroundPageToDispatchEvent(incognito_context, extension, 496 if (MaybeLoadLazyBackgroundPageToDispatchEvent(incognito_context, extension,
458 event, listener_filter)) { 497 event, listener_filter)) {
459 already_dispatched->insert( 498 already_dispatched->insert(
460 std::make_pair(incognito_context, extension_id)); 499 std::make_tuple(incognito_context, extension_id, kNonWorkerThreadId));
461 } 500 }
462 } 501 }
463 } 502 }
464 503
465 void EventRouter::DispatchEventToProcess( 504 void EventRouter::DispatchEventToProcess(
466 const std::string& extension_id, 505 const std::string& extension_id,
467 const GURL& listener_url, 506 const GURL& listener_url,
468 content::RenderProcessHost* process, 507 content::RenderProcessHost* process,
508 int worker_thread_id,
469 const linked_ptr<Event>& event, 509 const linked_ptr<Event>& event,
470 const base::DictionaryValue* listener_filter, 510 const base::DictionaryValue* listener_filter,
471 bool did_enqueue) { 511 bool did_enqueue) {
472 BrowserContext* listener_context = process->GetBrowserContext(); 512 BrowserContext* listener_context = process->GetBrowserContext();
473 ProcessMap* process_map = ProcessMap::Get(listener_context); 513 ProcessMap* process_map = ProcessMap::Get(listener_context);
474 514
475 // NOTE: |extension| being NULL does not necessarily imply that this event 515 // NOTE: |extension| being NULL does not necessarily imply that this event
476 // shouldn't be dispatched. Events can be dispatched to WebUI and webviews as 516 // shouldn't be dispatched. Events can be dispatched to WebUI and webviews as
477 // well. It all depends on what GetMostLikelyContextType returns. 517 // well. It all depends on what GetMostLikelyContextType returns.
478 const Extension* extension = 518 const Extension* extension =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 return; 566 return;
527 } 567 }
528 568
529 if (!event->will_dispatch_callback.is_null() && 569 if (!event->will_dispatch_callback.is_null() &&
530 !event->will_dispatch_callback.Run(listener_context, extension, 570 !event->will_dispatch_callback.Run(listener_context, extension,
531 event.get(), listener_filter)) { 571 event.get(), listener_filter)) {
532 return; 572 return;
533 } 573 }
534 574
535 int event_id = g_extension_event_id.GetNext(); 575 int event_id = g_extension_event_id.GetNext();
536 DispatchExtensionMessage(process, listener_context, extension_id, event_id, 576 DispatchExtensionMessage(process, worker_thread_id, listener_context,
537 event->event_name, event->event_args.get(), 577 extension_id, event_id, event->event_name,
538 event->user_gesture, event->filter_info); 578 event->event_args.get(), event->user_gesture,
579 event->filter_info);
539 580
540 if (extension) { 581 if (extension) {
541 ReportEvent(event->histogram_value, extension, did_enqueue); 582 ReportEvent(event->histogram_value, extension, did_enqueue);
542 IncrementInFlightEvents(listener_context, extension, event_id, 583 IncrementInFlightEvents(listener_context, extension, event_id,
543 event->event_name); 584 event->event_name);
544 } 585 }
545 } 586 }
546 587
547 bool EventRouter::CanDispatchEventToBrowserContext( 588 bool EventRouter::CanDispatchEventToBrowserContext(
548 BrowserContext* context, 589 BrowserContext* context,
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 } 740 }
700 } 741 }
701 } 742 }
702 743
703 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, 744 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event,
704 ExtensionHost* host) { 745 ExtensionHost* host) {
705 if (!host) 746 if (!host)
706 return; 747 return;
707 748
708 if (listeners_.HasProcessListener(host->render_process_host(), 749 if (listeners_.HasProcessListener(host->render_process_host(),
750 kNonWorkerThreadId,
709 host->extension()->id())) { 751 host->extension()->id())) {
710 DispatchEventToProcess(host->extension()->id(), host->GetURL(), 752 DispatchEventToProcess(host->extension()->id(), host->GetURL(),
711 host->render_process_host(), event, nullptr, 753 host->render_process_host(), kNonWorkerThreadId,
712 true /* did_enqueue */); 754 event, nullptr, true /* did_enqueue */);
713 } 755 }
714 } 756 }
715 757
716 void EventRouter::SetRegisteredEvents(const std::string& extension_id, 758 void EventRouter::SetRegisteredEvents(const std::string& extension_id,
717 const std::set<std::string>& events) { 759 const std::set<std::string>& events,
760 RegisteredEventType type) {
718 auto events_value = base::MakeUnique<base::ListValue>(); 761 auto events_value = base::MakeUnique<base::ListValue>();
719 for (std::set<std::string>::const_iterator iter = events.begin(); 762 for (std::set<std::string>::const_iterator iter = events.begin();
720 iter != events.end(); ++iter) { 763 iter != events.end(); ++iter) {
721 events_value->AppendString(*iter); 764 events_value->AppendString(*iter);
722 } 765 }
723 extension_prefs_->UpdateExtensionPref(extension_id, kRegisteredEvents, 766 const char* pref_key = type == RegisteredEventType::kLazy
767 ? kRegisteredLazyEvents
768 : kRegisteredServiceWorkerEvents;
769 extension_prefs_->UpdateExtensionPref(extension_id, pref_key,
724 std::move(events_value)); 770 std::move(events_value));
725 } 771 }
726 772
727 void EventRouter::AddFilterToEvent(const std::string& event_name, 773 void EventRouter::AddFilterToEvent(const std::string& event_name,
728 const std::string& extension_id, 774 const std::string& extension_id,
729 const DictionaryValue* filter) { 775 const DictionaryValue* filter) {
730 ExtensionPrefs::ScopedDictionaryUpdate update(extension_prefs_, extension_id, 776 ExtensionPrefs::ScopedDictionaryUpdate update(extension_prefs_, extension_id,
731 kFilteredEvents); 777 kFilteredEvents);
732 auto filtered_events = update.Create(); 778 auto filtered_events = update.Create();
733 779
734 ListValue* filter_list = nullptr; 780 ListValue* filter_list = nullptr;
735 if (!filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { 781 if (!filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) {
736 filtered_events->SetWithoutPathExpansion( 782 filtered_events->SetWithoutPathExpansion(
737 event_name, base::MakeUnique<base::ListValue>()); 783 event_name, base::MakeUnique<base::ListValue>());
738 filtered_events->GetListWithoutPathExpansion(event_name, &filter_list); 784 filtered_events->GetListWithoutPathExpansion(event_name, &filter_list);
739 } 785 }
740 786
741 filter_list->Append(filter->CreateDeepCopy()); 787 filter_list->Append(filter->CreateDeepCopy());
742 } 788 }
743 789
744 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, 790 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context,
745 const Extension* extension) { 791 const Extension* extension) {
746 // Add all registered lazy listeners to our cache. 792 // Add all registered lazy listeners to our cache.
793 // TODO(lazyboy): Load extension SW lazy events.
747 std::set<std::string> registered_events = 794 std::set<std::string> registered_events =
748 GetRegisteredEvents(extension->id()); 795 GetRegisteredEvents(extension->id(), RegisteredEventType::kLazy);
749 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); 796 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events);
797 // TODO(lazyboy): Load extension SW filtered events when they are available.
750 const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); 798 const DictionaryValue* filtered_events = GetFilteredEvents(extension->id());
751 if (filtered_events) 799 if (filtered_events)
752 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); 800 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events);
753 } 801 }
754 802
755 void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context, 803 void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context,
756 const Extension* extension, 804 const Extension* extension,
757 UnloadedExtensionReason reason) { 805 UnloadedExtensionReason reason) {
758 // Remove all registered listeners from our cache. 806 // Remove all registered listeners from our cache.
759 listeners_.RemoveListenersForExtension(extension->id()); 807 listeners_.RemoveListenersForExtension(extension->id());
760 } 808 }
761 809
810 void EventRouter::AddLazyEventListenerImpl(const std::string& event_name,
811 const ExtensionId& extension_id,
812 int worker_thread_id) {
813 bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId;
814 bool is_new = listeners_.AddListener(
815 is_for_service_worker
816 ? EventListener::ForExtensionServiceWorker(
817 event_name, extension_id, nullptr, worker_thread_id, nullptr)
818 : EventListener::ForExtension(event_name, extension_id, nullptr,
819 nullptr));
820
821 if (is_new) {
822 RegisteredEventType type = is_for_service_worker
823 ? RegisteredEventType::kServiceWorker
824 : RegisteredEventType::kLazy;
825 std::set<std::string> events = GetRegisteredEvents(extension_id, type);
826 bool prefs_is_new = events.insert(event_name).second;
827 if (prefs_is_new)
828 SetRegisteredEvents(extension_id, events, type);
829 }
830 }
831
832 void EventRouter::RemoveLazyEventListenerImpl(const std::string& event_name,
833 const ExtensionId& extension_id,
834 int worker_thread_id) {
835 bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId;
836 std::unique_ptr<EventListener> listener =
837 is_for_service_worker
838 ? EventListener::ForExtensionServiceWorker(
839 event_name, extension_id, nullptr, worker_thread_id, nullptr)
840 : EventListener::ForExtension(event_name, extension_id, nullptr,
841 nullptr);
842 bool did_exist = listeners_.RemoveListener(listener.get());
843
844 if (did_exist) {
845 RegisteredEventType type = is_for_service_worker
846 ? RegisteredEventType::kServiceWorker
847 : RegisteredEventType::kLazy;
848 std::set<std::string> events = GetRegisteredEvents(extension_id, type);
849 bool prefs_did_exist = events.erase(event_name) > 0;
850 DCHECK(prefs_did_exist);
851 SetRegisteredEvents(extension_id, events, type);
852 }
853 }
854
762 Event::Event(events::HistogramValue histogram_value, 855 Event::Event(events::HistogramValue histogram_value,
763 const std::string& event_name, 856 const std::string& event_name,
764 std::unique_ptr<base::ListValue> event_args) 857 std::unique_ptr<base::ListValue> event_args)
765 : Event(histogram_value, event_name, std::move(event_args), nullptr) {} 858 : Event(histogram_value, event_name, std::move(event_args), nullptr) {}
766 859
767 Event::Event(events::HistogramValue histogram_value, 860 Event::Event(events::HistogramValue histogram_value,
768 const std::string& event_name, 861 const std::string& event_name,
769 std::unique_ptr<base::ListValue> event_args, 862 std::unique_ptr<base::ListValue> event_args,
770 BrowserContext* restrict_to_browser_context) 863 BrowserContext* restrict_to_browser_context)
771 : Event(histogram_value, 864 : Event(histogram_value,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 const std::string& extension_id, 907 const std::string& extension_id,
815 const GURL& listener_url, 908 const GURL& listener_url,
816 content::BrowserContext* browser_context) 909 content::BrowserContext* browser_context)
817 : event_name(event_name), 910 : event_name(event_name),
818 extension_id(extension_id), 911 extension_id(extension_id),
819 listener_url(listener_url), 912 listener_url(listener_url),
820 browser_context(browser_context) { 913 browser_context(browser_context) {
821 } 914 }
822 915
823 } // namespace extensions 916 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/event_router.h ('k') | extensions/browser/extension_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698