Chromium Code Reviews| Index: extensions/browser/event_router.cc |
| diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc |
| index c39641884df439bfa7a110282b9ad3243d2e77da..a2fe5a85ec159103e746f19527e44024edfddd10 100644 |
| --- a/extensions/browser/event_router.cc |
| +++ b/extensions/browser/event_router.cc |
| @@ -72,10 +72,13 @@ base::StaticAtomicSequenceNumber g_extension_event_id; |
| } // namespace |
| -const char EventRouter::kRegisteredEvents[] = "events"; |
| +const char EventRouter::kRegisteredLazyEvents[] = "events"; |
| +const char EventRouter::kRegisteredServiceWorkerEvents[] = |
| + "serviceworkerevents"; |
| // static |
| void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, |
| + int worker_thread_id, |
| void* browser_context_id, |
| const std::string& extension_id, |
| int event_id, |
| @@ -87,6 +90,7 @@ void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, |
| *event_args); |
| ExtensionMsg_DispatchEvent_Params params; |
| + params.worker_thread_id = worker_thread_id; |
| params.extension_id = extension_id; |
| params.event_name = event_name; |
| params.event_id = event_id; |
| @@ -132,7 +136,10 @@ void EventRouter::DispatchEventToSender(IPC::Sender* ipc_sender, |
| event_name)); |
| } |
| - DispatchExtensionMessage(ipc_sender, browser_context_id, extension_id, |
| + DispatchExtensionMessage(ipc_sender, |
| + // TODO(lazyboy): |kNonWorkerThreadId| means these |
| + // will not work for extension SW. |
| + kNonWorkerThreadId, browser_context_id, extension_id, |
| event_id, event_name, event_args.get(), user_gesture, |
| info); |
| } |
| @@ -157,30 +164,50 @@ EventRouter::~EventRouter() { |
| void EventRouter::AddEventListener(const std::string& event_name, |
| content::RenderProcessHost* process, |
| const std::string& extension_id) { |
| - listeners_.AddListener(EventListener::ForExtension( |
| - event_name, extension_id, process, std::unique_ptr<DictionaryValue>())); |
| + listeners_.AddListener( |
| + EventListener::ForExtension(event_name, extension_id, process, nullptr)); |
| +} |
| + |
| +void EventRouter::AddServiceWorkerEventListener( |
| + const std::string& event_name, |
| + content::RenderProcessHost* process, |
| + const ExtensionId& extension_id, |
| + int worker_thread_id) { |
| + listeners_.AddListener(EventListener::ForExtensionServiceWorker( |
| + event_name, extension_id, process, worker_thread_id, nullptr)); |
| } |
| void EventRouter::RemoveEventListener(const std::string& event_name, |
| content::RenderProcessHost* process, |
| const std::string& extension_id) { |
| - std::unique_ptr<EventListener> listener = EventListener::ForExtension( |
| - event_name, extension_id, process, std::unique_ptr<DictionaryValue>()); |
| + std::unique_ptr<EventListener> listener = |
| + EventListener::ForExtension(event_name, extension_id, process, nullptr); |
| + listeners_.RemoveListener(listener.get()); |
| +} |
| + |
| +void EventRouter::RemoveServiceWorkerEventListener( |
| + const std::string& event_name, |
| + content::RenderProcessHost* process, |
| + const ExtensionId& extension_id, |
| + int worker_thread_id) { |
| + std::unique_ptr<EventListener> listener = |
| + EventListener::ForExtensionServiceWorker( |
| + event_name, extension_id, process, worker_thread_id, nullptr); |
| listeners_.RemoveListener(listener.get()); |
| } |
| void EventRouter::AddEventListenerForURL(const std::string& event_name, |
| content::RenderProcessHost* process, |
| const GURL& listener_url) { |
| - listeners_.AddListener(EventListener::ForURL( |
| - event_name, listener_url, process, std::unique_ptr<DictionaryValue>())); |
| + listeners_.AddListener( |
| + EventListener::ForURL(event_name, listener_url, process, nullptr)); |
| } |
| void EventRouter::RemoveEventListenerForURL(const std::string& event_name, |
| content::RenderProcessHost* process, |
| const GURL& listener_url) { |
| - std::unique_ptr<EventListener> listener = EventListener::ForURL( |
| - event_name, listener_url, process, std::unique_ptr<DictionaryValue>()); |
| + std::unique_ptr<EventListener> listener = |
| + EventListener::ForURL(event_name, listener_url, process, nullptr); |
| listeners_.RemoveListener(listener.get()); |
| } |
| @@ -243,33 +270,76 @@ void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) { |
| host->RemoveObserver(this); |
| } |
| -void EventRouter::AddLazyEventListener(const std::string& event_name, |
| - const std::string& extension_id) { |
| - bool is_new = listeners_.AddListener(EventListener::ForExtension( |
| - event_name, extension_id, NULL, std::unique_ptr<DictionaryValue>())); |
| +void EventRouter::AddLazyEventListenerImpl(const std::string& event_name, |
|
Devlin
2017/06/01 04:54:49
Where possible, definition order should match decl
lazyboy
2017/06/01 23:33:29
I've intentionally kept it this way, otherwise the
lazyboy
2017/06/02 17:58:59
Moved this after OnExtensionUnloaded to match .h i
|
| + const ExtensionId& extension_id, |
| + int worker_thread_id) { |
| + bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId; |
| + bool is_new = listeners_.AddListener( |
| + is_for_service_worker |
| + ? EventListener::ForExtensionServiceWorker( |
| + event_name, extension_id, nullptr, worker_thread_id, nullptr) |
| + : EventListener::ForExtension(event_name, extension_id, nullptr, |
| + nullptr)); |
| if (is_new) { |
| - std::set<std::string> events = GetRegisteredEvents(extension_id); |
| + RegisteredEventType type = is_for_service_worker |
| + ? RegisteredEventType::kServiceWorker |
| + : RegisteredEventType::kLazy; |
| + std::set<std::string> events = GetRegisteredEvents(extension_id, type); |
| bool prefs_is_new = events.insert(event_name).second; |
| if (prefs_is_new) |
| - SetRegisteredEvents(extension_id, events); |
| + SetRegisteredEvents(extension_id, events, type); |
| } |
| } |
| -void EventRouter::RemoveLazyEventListener(const std::string& event_name, |
| - const std::string& extension_id) { |
| - std::unique_ptr<EventListener> listener = EventListener::ForExtension( |
| - event_name, extension_id, NULL, std::unique_ptr<DictionaryValue>()); |
| +void EventRouter::RemoveLazyEventListenerImpl(const std::string& event_name, |
| + const ExtensionId& extension_id, |
| + int worker_thread_id) { |
| + bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId; |
| + std::unique_ptr<EventListener> listener = |
| + is_for_service_worker |
| + ? EventListener::ForExtensionServiceWorker( |
| + event_name, extension_id, nullptr, worker_thread_id, nullptr) |
| + : EventListener::ForExtension(event_name, extension_id, nullptr, |
| + nullptr); |
| bool did_exist = listeners_.RemoveListener(listener.get()); |
| if (did_exist) { |
| - std::set<std::string> events = GetRegisteredEvents(extension_id); |
| + RegisteredEventType type = is_for_service_worker |
| + ? RegisteredEventType::kServiceWorker |
| + : RegisteredEventType::kLazy; |
| + std::set<std::string> events = GetRegisteredEvents(extension_id, type); |
| bool prefs_did_exist = events.erase(event_name) > 0; |
| DCHECK(prefs_did_exist); |
| - SetRegisteredEvents(extension_id, events); |
| + SetRegisteredEvents(extension_id, events, type); |
| } |
| } |
| +void EventRouter::AddLazyEventListener(const std::string& event_name, |
| + const ExtensionId& extension_id) { |
| + AddLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId); |
| +} |
| + |
| +void EventRouter::RemoveLazyEventListener(const std::string& event_name, |
| + const ExtensionId& extension_id) { |
| + RemoveLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId); |
| +} |
| + |
| +void EventRouter::AddLazyServiceWorkerEventListener( |
| + const std::string& event_name, |
| + const ExtensionId& extension_id, |
| + int worker_thread_id) { |
| + AddLazyEventListenerImpl(event_name, extension_id, worker_thread_id); |
| +} |
| + |
| +void EventRouter::RemoveLazyServiceWorkerEventListener( |
| + const std::string& event_name, |
| + const ExtensionId& extension_id, |
| + int worker_thread_id) { |
| + RemoveLazyEventListenerImpl(event_name, extension_id, worker_thread_id); |
| +} |
| + |
| +// TODO(lazyboy): Support filters for extension SW events. |
| void EventRouter::AddFilteredEventListener(const std::string& event_name, |
| content::RenderProcessHost* process, |
| const std::string& extension_id, |
| @@ -289,6 +359,7 @@ void EventRouter::AddFilteredEventListener(const std::string& event_name, |
| AddFilterToEvent(event_name, extension_id, &filter); |
| } |
| +// TODO(lazyboy): Support filters for extension SW events. |
| void EventRouter::RemoveFilteredEventListener( |
| const std::string& event_name, |
| content::RenderProcessHost* process, |
| @@ -321,13 +392,16 @@ bool EventRouter::ExtensionHasEventListener( |
| } |
| std::set<std::string> EventRouter::GetRegisteredEvents( |
| - const std::string& extension_id) const { |
| + const std::string& extension_id, |
| + RegisteredEventType type) const { |
| std::set<std::string> events; |
| const ListValue* events_value = NULL; |
| - if (!extension_prefs_ || |
| - !extension_prefs_->ReadPrefAsList( |
| - extension_id, kRegisteredEvents, &events_value)) { |
| + const char* pref_key = type == RegisteredEventType::kLazy |
| + ? kRegisteredLazyEvents |
| + : kRegisteredServiceWorkerEvents; |
| + if (!extension_prefs_ || !extension_prefs_->ReadPrefAsList( |
| + extension_id, pref_key, &events_value)) { |
| return events; |
| } |
| @@ -339,6 +413,14 @@ std::set<std::string> EventRouter::GetRegisteredEvents( |
| return events; |
| } |
| +void EventRouter::ClearRegisteredEventsForTest( |
| + const ExtensionId& extension_id) { |
| + SetRegisteredEvents(extension_id, std::set<std::string>(), |
| + RegisteredEventType::kLazy); |
| + SetRegisteredEvents(extension_id, std::set<std::string>(), |
| + RegisteredEventType::kServiceWorker); |
| +} |
| + |
| void EventRouter::RemoveFilterFromEvent(const std::string& event_name, |
| const std::string& extension_id, |
| const DictionaryValue* filter) { |
| @@ -397,7 +479,6 @@ void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, |
| DCHECK(!event->restrict_to_browser_context || |
| ExtensionsBrowserClient::Get()->IsSameContext( |
| browser_context_, event->restrict_to_browser_context)); |
| - |
| std::set<const EventListener*> listeners( |
| listeners_.GetEventListeners(*event)); |
| @@ -412,7 +493,8 @@ void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, |
| for (const EventListener* listener : listeners) { |
| if (restrict_to_extension_id.empty() || |
| restrict_to_extension_id == listener->extension_id()) { |
| - if (listener->IsLazy()) { |
| + // TODO(lazyboy): Support lazy listeners for extension SW events. |
| + if (listener->IsLazy() && !listener->IsForServiceWorker()) { |
| DispatchLazyEvent(listener->extension_id(), event, &already_dispatched, |
| listener->filter()); |
| } |
| @@ -424,12 +506,13 @@ void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, |
| restrict_to_extension_id == listener->extension_id()) { |
| if (listener->process()) { |
| EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), |
| - listener->extension_id()); |
| + listener->extension_id(), |
| + listener->worker_thread_id()); |
| if (!base::ContainsKey(already_dispatched, dispatch_id)) { |
| DispatchEventToProcess(listener->extension_id(), |
| listener->listener_url(), listener->process(), |
| - event, listener->filter(), |
| - false /* did_enqueue */); |
| + listener->worker_thread_id(), event, |
| + listener->filter(), false /* did_enqueue */); |
| } |
| } |
| } |
| @@ -452,7 +535,8 @@ void EventRouter::DispatchLazyEvent( |
| if (MaybeLoadLazyBackgroundPageToDispatchEvent(browser_context_, extension, |
| event, listener_filter)) { |
| - already_dispatched->insert(std::make_pair(browser_context_, extension_id)); |
| + already_dispatched->insert( |
| + std::make_tuple(browser_context_, extension_id, kNonWorkerThreadId)); |
| } |
| ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get(); |
| @@ -463,7 +547,7 @@ void EventRouter::DispatchLazyEvent( |
| if (MaybeLoadLazyBackgroundPageToDispatchEvent(incognito_context, extension, |
| event, listener_filter)) { |
| already_dispatched->insert( |
| - std::make_pair(incognito_context, extension_id)); |
| + std::make_tuple(incognito_context, extension_id, kNonWorkerThreadId)); |
| } |
| } |
| } |
| @@ -472,6 +556,7 @@ void EventRouter::DispatchEventToProcess( |
| const std::string& extension_id, |
| const GURL& listener_url, |
| content::RenderProcessHost* process, |
| + int worker_thread_id, |
| const linked_ptr<Event>& event, |
| const base::DictionaryValue* listener_filter, |
| bool did_enqueue) { |
| @@ -539,9 +624,10 @@ void EventRouter::DispatchEventToProcess( |
| } |
| int event_id = g_extension_event_id.GetNext(); |
| - DispatchExtensionMessage(process, listener_context, extension_id, event_id, |
| - event->event_name, event->event_args.get(), |
| - event->user_gesture, event->filter_info); |
| + DispatchExtensionMessage(process, worker_thread_id, listener_context, |
| + extension_id, event_id, event->event_name, |
| + event->event_args.get(), event->user_gesture, |
| + event->filter_info); |
| if (extension) { |
| ReportEvent(event->histogram_value, extension, did_enqueue); |
| @@ -712,21 +798,26 @@ void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, |
| return; |
| if (listeners_.HasProcessListener(host->render_process_host(), |
| + kNonWorkerThreadId, |
| host->extension()->id())) { |
| DispatchEventToProcess(host->extension()->id(), host->GetURL(), |
| - host->render_process_host(), event, nullptr, |
| - true /* did_enqueue */); |
| + host->render_process_host(), kNonWorkerThreadId, |
| + event, nullptr, true /* did_enqueue */); |
| } |
| } |
| void EventRouter::SetRegisteredEvents(const std::string& extension_id, |
| - const std::set<std::string>& events) { |
| + const std::set<std::string>& events, |
| + RegisteredEventType type) { |
| auto events_value = base::MakeUnique<base::ListValue>(); |
| for (std::set<std::string>::const_iterator iter = events.begin(); |
| iter != events.end(); ++iter) { |
| events_value->AppendString(*iter); |
| } |
| - extension_prefs_->UpdateExtensionPref(extension_id, kRegisteredEvents, |
| + const char* pref_key = type == RegisteredEventType::kLazy |
| + ? kRegisteredLazyEvents |
| + : kRegisteredServiceWorkerEvents; |
| + extension_prefs_->UpdateExtensionPref(extension_id, pref_key, |
| std::move(events_value)); |
| } |
| @@ -767,9 +858,11 @@ void EventRouter::Observe(int type, |
| void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, |
| const Extension* extension) { |
| // Add all registered lazy listeners to our cache. |
| + // TODO(lazyboy): Load extension SW lazy events. |
| std::set<std::string> registered_events = |
| - GetRegisteredEvents(extension->id()); |
| + GetRegisteredEvents(extension->id(), RegisteredEventType::kLazy); |
| listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); |
| + // TODO(lazyboy): Load extension SW filtered events when they are available. |
| const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); |
| if (filtered_events) |
| listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); |