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

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

Issue 2924213002: Draft: Dispatching extension events to stopped extension SW.
Patch Set: rebase @tott 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/events/lazy_event_dispatcher.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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 content::RenderProcessHost* process, 174 content::RenderProcessHost* process,
175 const std::string& extension_id) { 175 const std::string& extension_id) {
176 listeners_.AddListener( 176 listeners_.AddListener(
177 EventListener::ForExtension(event_name, extension_id, process, nullptr)); 177 EventListener::ForExtension(event_name, extension_id, process, nullptr));
178 } 178 }
179 179
180 void EventRouter::AddServiceWorkerEventListener( 180 void EventRouter::AddServiceWorkerEventListener(
181 const std::string& event_name, 181 const std::string& event_name,
182 content::RenderProcessHost* process, 182 content::RenderProcessHost* process,
183 const ExtensionId& extension_id, 183 const ExtensionId& extension_id,
184 const GURL& service_worker_scope,
184 int worker_thread_id) { 185 int worker_thread_id) {
185 listeners_.AddListener(EventListener::ForExtensionServiceWorker( 186 listeners_.AddListener(EventListener::ForExtensionServiceWorker(
186 event_name, extension_id, process, worker_thread_id, nullptr)); 187 event_name, extension_id, process, service_worker_scope, worker_thread_id,
188 nullptr));
187 } 189 }
188 190
189 void EventRouter::RemoveEventListener(const std::string& event_name, 191 void EventRouter::RemoveEventListener(const std::string& event_name,
190 content::RenderProcessHost* process, 192 content::RenderProcessHost* process,
191 const std::string& extension_id) { 193 const std::string& extension_id) {
192 std::unique_ptr<EventListener> listener = 194 std::unique_ptr<EventListener> listener =
193 EventListener::ForExtension(event_name, extension_id, process, nullptr); 195 EventListener::ForExtension(event_name, extension_id, process, nullptr);
194 listeners_.RemoveListener(listener.get()); 196 listeners_.RemoveListener(listener.get());
195 } 197 }
196 198
197 void EventRouter::RemoveServiceWorkerEventListener( 199 void EventRouter::RemoveServiceWorkerEventListener(
198 const std::string& event_name, 200 const std::string& event_name,
199 content::RenderProcessHost* process, 201 content::RenderProcessHost* process,
200 const ExtensionId& extension_id, 202 const ExtensionId& extension_id,
203 const GURL& service_worker_scope,
201 int worker_thread_id) { 204 int worker_thread_id) {
202 std::unique_ptr<EventListener> listener = 205 std::unique_ptr<EventListener> listener =
203 EventListener::ForExtensionServiceWorker( 206 EventListener::ForExtensionServiceWorker(event_name, extension_id,
204 event_name, extension_id, process, worker_thread_id, nullptr); 207 process, service_worker_scope,
208 worker_thread_id, nullptr);
205 listeners_.RemoveListener(listener.get()); 209 listeners_.RemoveListener(listener.get());
206 } 210 }
207 211
208 void EventRouter::AddEventListenerForURL(const std::string& event_name, 212 void EventRouter::AddEventListenerForURL(const std::string& event_name,
209 content::RenderProcessHost* process, 213 content::RenderProcessHost* process,
210 const GURL& listener_url) { 214 const GURL& listener_url) {
211 listeners_.AddListener( 215 listeners_.AddListener(
212 EventListener::ForURL(event_name, listener_url, process, nullptr)); 216 EventListener::ForURL(event_name, listener_url, process, nullptr));
213 } 217 }
214 218
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 } 278 }
275 279
276 void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) { 280 void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) {
277 listeners_.RemoveListenersForProcess(host); 281 listeners_.RemoveListenersForProcess(host);
278 observed_process_set_.erase(host); 282 observed_process_set_.erase(host);
279 host->RemoveObserver(this); 283 host->RemoveObserver(this);
280 } 284 }
281 285
282 void EventRouter::AddLazyEventListener(const std::string& event_name, 286 void EventRouter::AddLazyEventListener(const std::string& event_name,
283 const ExtensionId& extension_id) { 287 const ExtensionId& extension_id) {
284 AddLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId); 288 AddLazyEventListenerImpl(
289 EventListener::ForExtension(event_name, extension_id, nullptr, nullptr),
290 RegisteredEventType::kLazy);
285 } 291 }
286 292
287 void EventRouter::RemoveLazyEventListener(const std::string& event_name, 293 void EventRouter::RemoveLazyEventListener(const std::string& event_name,
288 const ExtensionId& extension_id) { 294 const ExtensionId& extension_id) {
289 RemoveLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId); 295 RemoveLazyEventListenerImpl(
296 EventListener::ForExtension(event_name, extension_id, nullptr, nullptr),
297 RegisteredEventType::kLazy);
290 } 298 }
291 299
292 void EventRouter::AddLazyServiceWorkerEventListener( 300 void EventRouter::AddLazyServiceWorkerEventListener(
293 const std::string& event_name, 301 const std::string& event_name,
294 const ExtensionId& extension_id, 302 const ExtensionId& extension_id,
295 int worker_thread_id) { 303 const GURL& service_worker_scope) {
296 AddLazyEventListenerImpl(event_name, extension_id, worker_thread_id); 304 std::unique_ptr<EventListener> listener =
305 EventListener::ForExtensionServiceWorker(
306 event_name, extension_id, nullptr, service_worker_scope,
307 kNonWorkerThreadId, // Lazy, without worker thread id.
308 nullptr);
309 AddLazyEventListenerImpl(std::move(listener),
310 RegisteredEventType::kServiceWorker);
297 } 311 }
298 312
299 void EventRouter::RemoveLazyServiceWorkerEventListener( 313 void EventRouter::RemoveLazyServiceWorkerEventListener(
300 const std::string& event_name, 314 const std::string& event_name,
301 const ExtensionId& extension_id, 315 const ExtensionId& extension_id,
302 int worker_thread_id) { 316 const GURL& service_worker_scope) {
303 RemoveLazyEventListenerImpl(event_name, extension_id, worker_thread_id); 317 std::unique_ptr<EventListener> listener =
318 EventListener::ForExtensionServiceWorker(
319 event_name, extension_id, nullptr, service_worker_scope,
320 kNonWorkerThreadId, // Lazy, without worker thread id.
321 nullptr);
322 RemoveLazyEventListenerImpl(std::move(listener),
323 RegisteredEventType::kServiceWorker);
304 } 324 }
305 325
306 // TODO(lazyboy): Support filters for extension SW events. 326 // TODO(lazyboy): Support filters for extension SW events.
307 void EventRouter::AddFilteredEventListener(const std::string& event_name, 327 void EventRouter::AddFilteredEventListener(const std::string& event_name,
308 content::RenderProcessHost* process, 328 content::RenderProcessHost* process,
309 const std::string& extension_id, 329 const std::string& extension_id,
310 const base::DictionaryValue& filter, 330 const base::DictionaryValue& filter,
311 bool add_lazy_listener) { 331 bool add_lazy_listener) {
312 listeners_.AddListener(EventListener::ForExtension( 332 listeners_.AddListener(EventListener::ForExtension(
313 event_name, extension_id, process, 333 event_name, extension_id, process,
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 if (!has_listener) 456 if (!has_listener)
437 RemoveLazyEventListener(event_name, extension_id); 457 RemoveLazyEventListener(event_name, extension_id);
438 } 458 }
439 459
440 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, 460 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id,
441 const linked_ptr<Event>& event) { 461 const linked_ptr<Event>& event) {
442 // We don't expect to get events from a completely different browser context. 462 // We don't expect to get events from a completely different browser context.
443 DCHECK(!event->restrict_to_browser_context || 463 DCHECK(!event->restrict_to_browser_context ||
444 ExtensionsBrowserClient::Get()->IsSameContext( 464 ExtensionsBrowserClient::Get()->IsSameContext(
445 browser_context_, event->restrict_to_browser_context)); 465 browser_context_, event->restrict_to_browser_context));
466 LOG(ERROR) << "ER::DispatchEventImpl, event_name: " << event->event_name
467 << ", restrict_to_extension_id: " << restrict_to_extension_id;
468 bool is_tabs_on_updated_event = event->event_name == "tabs.onUpdated";
446 std::set<const EventListener*> listeners( 469 std::set<const EventListener*> listeners(
447 listeners_.GetEventListeners(*event)); 470 listeners_.GetEventListeners(*event));
448 471
449 LazyEventDispatcher lazy_event_dispatcher( 472 LazyEventDispatcher lazy_event_dispatcher(
450 browser_context_, event, 473 browser_context_, event,
451 base::Bind(&EventRouter::DispatchPendingEvent, 474 base::Bind(&EventRouter::DispatchPendingEvent,
452 weak_factory_.GetWeakPtr())); 475 weak_factory_.GetWeakPtr()));
453 476
454 // We dispatch events for lazy background pages first because attempting to do 477 // We dispatch events for lazy background pages first because attempting to do
455 // so will cause those that are being suspended to cancel that suspension. 478 // so will cause those that are being suspended to cancel that suspension.
456 // As canceling a suspension entails sending an event to the affected 479 // As canceling a suspension entails sending an event to the affected
457 // background page, and as that event needs to be delivered before we dispatch 480 // background page, and as that event needs to be delivered before we dispatch
458 // the event we are dispatching here, we dispatch to the lazy listeners here 481 // the event we are dispatching here, we dispatch to the lazy listeners here
459 // first. 482 // first.
460 for (const EventListener* listener : listeners) { 483 for (const EventListener* listener : listeners) {
484 if (is_tabs_on_updated_event) {
485 LOG(ERROR) << "tabs.onUpdated: listener->process = "
486 << listener->process() << ", listener->worker_thread_id() = "
487 << listener->worker_thread_id() << ", is_for_service_worker: "
488 << listener->is_for_service_worker()
489 << ", IsLazy: " << listener->IsLazy();
490 }
461 if (!restrict_to_extension_id.empty() && 491 if (!restrict_to_extension_id.empty() &&
462 restrict_to_extension_id != listener->extension_id()) { 492 restrict_to_extension_id != listener->extension_id()) {
463 continue; 493 continue;
464 } 494 }
465 // TODO(lazyboy): Support lazy listeners for extension SW events. 495 if (listener->IsLazy()) {
466 if (listener->IsLazy() && !listener->IsForServiceWorker()) { 496 if (listener->is_for_service_worker()) {
467 lazy_event_dispatcher.DispatchToEventPage(listener->extension_id(), 497 if (is_tabs_on_updated_event)
468 listener->filter()); 498 LOG(ERROR) << "---> DISPATCH branch 2";
499 lazy_event_dispatcher.DispatchToServiceWorker(
500 listener->extension_id(), listener->listener_url(), nullptr);
501 } else {
502 lazy_event_dispatcher.DispatchToEventPage(listener->extension_id(),
503 listener->filter());
504 }
469 } 505 }
470 } 506 }
471 507
472 for (const EventListener* listener : listeners) { 508 for (const EventListener* listener : listeners) {
473 if (!restrict_to_extension_id.empty() && 509 if (!restrict_to_extension_id.empty() &&
474 restrict_to_extension_id != listener->extension_id()) { 510 restrict_to_extension_id != listener->extension_id()) {
475 continue; 511 continue;
476 } 512 }
477 if (!listener->process()) 513 if (!listener->process())
478 continue; 514 continue;
515 if (is_tabs_on_updated_event)
516 LOG(ERROR) << "---> DISPATCH branch 2";
479 if (lazy_event_dispatcher.HasAlreadyDispatched( 517 if (lazy_event_dispatcher.HasAlreadyDispatched(
480 listener->process()->GetBrowserContext(), listener)) { 518 listener->process()->GetBrowserContext(), listener)) {
519 if (is_tabs_on_updated_event)
520 LOG(ERROR) << "SKIP^^^";
481 continue; 521 continue;
482 } 522 }
523
483 DispatchEventToProcess(listener->extension_id(), listener->listener_url(), 524 DispatchEventToProcess(listener->extension_id(), listener->listener_url(),
484 listener->process(), listener->worker_thread_id(), 525 listener->process(), listener->worker_thread_id(),
485 event, listener->filter(), false /* did_enqueue */); 526 event, listener->filter(), false /* did_enqueue */);
486 } 527 }
487 } 528 }
488 529
489 void EventRouter::DispatchEventToProcess( 530 void EventRouter::DispatchEventToProcess(
490 const std::string& extension_id, 531 const std::string& extension_id,
491 const GURL& listener_url, 532 const GURL& listener_url,
492 content::RenderProcessHost* process, 533 content::RenderProcessHost* process,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 event.get(), listener_filter)) { 598 event.get(), listener_filter)) {
558 return; 599 return;
559 } 600 }
560 601
561 int event_id = g_extension_event_id.GetNext(); 602 int event_id = g_extension_event_id.GetNext();
562 DispatchExtensionMessage(process, worker_thread_id, listener_context, 603 DispatchExtensionMessage(process, worker_thread_id, listener_context,
563 extension_id, event_id, event->event_name, 604 extension_id, event_id, event->event_name,
564 event->event_args.get(), event->user_gesture, 605 event->event_args.get(), event->user_gesture,
565 event->filter_info); 606 event->filter_info);
566 607
608 // TODO(lazyboy): This is wrong for extensions SW events. We need to:
609 // 1. Increment worker ref count
610 // 2. Add EventAck IPC to decrement that ref count.
567 if (extension) { 611 if (extension) {
568 ReportEvent(event->histogram_value, extension, did_enqueue); 612 ReportEvent(event->histogram_value, extension, did_enqueue);
569 IncrementInFlightEvents(listener_context, extension, event_id, 613 IncrementInFlightEvents(listener_context, extension, event_id,
570 event->event_name); 614 event->event_name);
571 } 615 }
572 } 616 }
573 617
574 // static 618 // static
575 void EventRouter::DoDispatchEventToSenderBookkeepingOnUI( 619 void EventRouter::DoDispatchEventToSenderBookkeepingOnUI(
576 void* browser_context_id, 620 void* browser_context_id,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 histogram_value, events::ENUM_BOUNDARY); 716 histogram_value, events::ENUM_BOUNDARY);
673 } 717 }
674 } else { 718 } else {
675 UMA_HISTOGRAM_ENUMERATION( 719 UMA_HISTOGRAM_ENUMERATION(
676 "Extensions.Events.DispatchWithRunningEventPage", histogram_value, 720 "Extensions.Events.DispatchWithRunningEventPage", histogram_value,
677 events::ENUM_BOUNDARY); 721 events::ENUM_BOUNDARY);
678 } 722 }
679 } 723 }
680 } 724 }
681 725
682 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, 726 void EventRouter::DispatchPendingEvent(
683 ExtensionHost* host) { 727 const linked_ptr<Event>& event,
684 if (!host) 728 std::unique_ptr<LazyContextTaskQueue::ContextInfo> params) {
729 if (!params)
685 return; 730 return;
686 731
687 if (listeners_.HasProcessListener(host->render_process_host(), 732 if (event->event_name == "tabs.onUpdated")
688 kNonWorkerThreadId, 733 LOG(ERROR) << "DispatchPendingEvent";
689 host->extension()->id())) { 734
690 DispatchEventToProcess(host->extension()->id(), host->GetURL(), 735 if (listeners_.HasProcessListener(params->render_process_host,
691 host->render_process_host(), kNonWorkerThreadId, 736 params->worker_thread_id,
692 event, nullptr, true /* did_enqueue */); 737 params->extension_id)) {
738 DispatchEventToProcess(
739 params->extension_id, params->url, params->render_process_host,
740 params->worker_thread_id, event, nullptr, true /* did_enqueue */);
693 } 741 }
694 } 742 }
695 743
696 void EventRouter::SetRegisteredEvents(const std::string& extension_id, 744 void EventRouter::SetRegisteredEvents(const std::string& extension_id,
697 const std::set<std::string>& events, 745 const std::set<std::string>& events,
698 RegisteredEventType type) { 746 RegisteredEventType type) {
699 auto events_value = base::MakeUnique<base::ListValue>(); 747 auto events_value = base::MakeUnique<base::ListValue>();
700 for (std::set<std::string>::const_iterator iter = events.begin(); 748 for (std::set<std::string>::const_iterator iter = events.begin();
701 iter != events.end(); ++iter) { 749 iter != events.end(); ++iter) {
702 events_value->AppendString(*iter); 750 events_value->AppendString(*iter);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); 786 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events);
739 } 787 }
740 788
741 void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context, 789 void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context,
742 const Extension* extension, 790 const Extension* extension,
743 UnloadedExtensionReason reason) { 791 UnloadedExtensionReason reason) {
744 // Remove all registered listeners from our cache. 792 // Remove all registered listeners from our cache.
745 listeners_.RemoveListenersForExtension(extension->id()); 793 listeners_.RemoveListenersForExtension(extension->id());
746 } 794 }
747 795
748 void EventRouter::AddLazyEventListenerImpl(const std::string& event_name, 796 void EventRouter::AddLazyEventListenerImpl(
749 const ExtensionId& extension_id, 797 std::unique_ptr<EventListener> listener,
750 int worker_thread_id) { 798 RegisteredEventType type) {
751 bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId; 799 const ExtensionId& extension_id = listener->extension_id();
752 bool is_new = listeners_.AddListener( 800 const std::string& event_name = listener->event_name();
753 is_for_service_worker 801 bool is_new = listeners_.AddListener(std::move(listener));
754 ? EventListener::ForExtensionServiceWorker(
755 event_name, extension_id, nullptr, worker_thread_id, nullptr)
756 : EventListener::ForExtension(event_name, extension_id, nullptr,
757 nullptr));
758
759 if (is_new) { 802 if (is_new) {
760 RegisteredEventType type = is_for_service_worker
761 ? RegisteredEventType::kServiceWorker
762 : RegisteredEventType::kLazy;
763 std::set<std::string> events = GetRegisteredEvents(extension_id, type); 803 std::set<std::string> events = GetRegisteredEvents(extension_id, type);
764 bool prefs_is_new = events.insert(event_name).second; 804 bool prefs_is_new = events.insert(event_name).second;
765 if (prefs_is_new) 805 if (prefs_is_new)
766 SetRegisteredEvents(extension_id, events, type); 806 SetRegisteredEvents(extension_id, events, type);
767 } 807 }
768 } 808 }
769 809
770 void EventRouter::RemoveLazyEventListenerImpl(const std::string& event_name, 810 void EventRouter::RemoveLazyEventListenerImpl(
771 const ExtensionId& extension_id, 811 std::unique_ptr<EventListener> listener,
772 int worker_thread_id) { 812 RegisteredEventType type) {
773 bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId; 813 const ExtensionId& extension_id = listener->extension_id();
774 std::unique_ptr<EventListener> listener = 814 const std::string& event_name = listener->event_name();
775 is_for_service_worker
776 ? EventListener::ForExtensionServiceWorker(
777 event_name, extension_id, nullptr, worker_thread_id, nullptr)
778 : EventListener::ForExtension(event_name, extension_id, nullptr,
779 nullptr);
780 bool did_exist = listeners_.RemoveListener(listener.get()); 815 bool did_exist = listeners_.RemoveListener(listener.get());
781
782 if (did_exist) { 816 if (did_exist) {
783 RegisteredEventType type = is_for_service_worker
784 ? RegisteredEventType::kServiceWorker
785 : RegisteredEventType::kLazy;
786 std::set<std::string> events = GetRegisteredEvents(extension_id, type); 817 std::set<std::string> events = GetRegisteredEvents(extension_id, type);
787 bool prefs_did_exist = events.erase(event_name) > 0; 818 bool prefs_did_exist = events.erase(event_name) > 0;
788 DCHECK(prefs_did_exist); 819 DCHECK(prefs_did_exist);
789 SetRegisteredEvents(extension_id, events, type); 820 SetRegisteredEvents(extension_id, events, type);
790 } 821 }
791 } 822 }
792 823
793 Event::Event(events::HistogramValue histogram_value, 824 Event::Event(events::HistogramValue histogram_value,
794 const std::string& event_name, 825 const std::string& event_name,
795 std::unique_ptr<base::ListValue> event_args) 826 std::unique_ptr<base::ListValue> event_args)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 const std::string& extension_id, 876 const std::string& extension_id,
846 const GURL& listener_url, 877 const GURL& listener_url,
847 content::BrowserContext* browser_context) 878 content::BrowserContext* browser_context)
848 : event_name(event_name), 879 : event_name(event_name),
849 extension_id(extension_id), 880 extension_id(extension_id),
850 listener_url(listener_url), 881 listener_url(listener_url),
851 browser_context(browser_context) { 882 browser_context(browser_context) {
852 } 883 }
853 884
854 } // namespace extensions 885 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/event_router.h ('k') | extensions/browser/events/lazy_event_dispatcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698