Chromium Code Reviews| Index: extensions/browser/event_router.cc |
| diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc |
| index 72121ead18dcbac98e7369b831b7bf6a4d8e5521..0afadd9fb9bdaa54a90a0dc8c26d695fd90960cf 100644 |
| --- a/extensions/browser/event_router.cc |
| +++ b/extensions/browser/event_router.cc |
| @@ -74,10 +74,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, |
| @@ -89,6 +92,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; |
| @@ -134,7 +138,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); |
| } |
| @@ -163,6 +170,16 @@ void EventRouter::AddEventListener(const std::string& event_name, |
| event_name, extension_id, process, std::unique_ptr<DictionaryValue>())); |
| } |
| +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, |
| + std::unique_ptr<DictionaryValue>())); |
|
Devlin
2017/05/24 17:58:25
nit: could just pass nullptr
lazyboy
2017/05/25 01:33:43
Done.
|
| +} |
| + |
| void EventRouter::RemoveEventListener(const std::string& event_name, |
| content::RenderProcessHost* process, |
| const std::string& extension_id) { |
| @@ -171,6 +188,18 @@ void EventRouter::RemoveEventListener(const std::string& event_name, |
| 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, |
| + std::unique_ptr<DictionaryValue>()); |
| + listeners_.RemoveListener(listener.get()); |
| +} |
| + |
| void EventRouter::AddEventListenerForURL(const std::string& event_name, |
| content::RenderProcessHost* process, |
| const GURL& listener_url) { |
| @@ -247,33 +276,78 @@ 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, |
| + 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, |
| + std::unique_ptr<DictionaryValue>()) |
| + : EventListener::ForExtension(event_name, extension_id, nullptr, |
| + std::unique_ptr<DictionaryValue>())); |
| if (is_new) { |
| - std::set<std::string> events = GetRegisteredEvents(extension_id); |
| + std::set<std::string> events = GetRegisteredEvents( |
| + extension_id, is_for_service_worker ? kRegisteredServiceWorkerEvents |
| + : kRegisteredLazyEvents); |
| bool prefs_is_new = events.insert(event_name).second; |
| - if (prefs_is_new) |
| - SetRegisteredEvents(extension_id, events); |
| + if (prefs_is_new) { |
| + SetRegisteredEvents(extension_id, events, |
| + is_for_service_worker ? kRegisteredServiceWorkerEvents |
| + : kRegisteredLazyEvents); |
| + } |
| } |
| } |
| -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, |
| + std::unique_ptr<DictionaryValue>()) |
| + : EventListener::ForExtension(event_name, extension_id, nullptr, |
| + std::unique_ptr<DictionaryValue>()); |
| bool did_exist = listeners_.RemoveListener(listener.get()); |
| if (did_exist) { |
| - std::set<std::string> events = GetRegisteredEvents(extension_id); |
| + std::set<std::string> events = |
| + GetRegisteredEvents(extension_id, kRegisteredLazyEvents); |
|
Devlin
2017/05/24 17:58:25
Do we need to check is_for_service_worker here?
lazyboy
2017/05/25 01:33:43
Done.
|
| bool prefs_did_exist = events.erase(event_name) > 0; |
| DCHECK(prefs_did_exist); |
| - SetRegisteredEvents(extension_id, events); |
| + SetRegisteredEvents(extension_id, events, kRegisteredLazyEvents); |
| } |
| } |
| +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, |
| @@ -285,7 +359,7 @@ void EventRouter::AddFilteredEventListener(const std::string& event_name, |
| if (add_lazy_listener) { |
| bool added = listeners_.AddListener(EventListener::ForExtension( |
| - event_name, extension_id, NULL, |
| + event_name, extension_id, nullptr, |
| std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
| if (added) |
| @@ -293,6 +367,7 @@ void EventRouter::AddFilteredEventListener(const std::string& event_name, |
| } |
| } |
| +// TODO(lazyboy): Support filters for extension SW events. |
| void EventRouter::RemoveFilteredEventListener( |
| const std::string& event_name, |
| content::RenderProcessHost* process, |
| @@ -324,13 +399,13 @@ bool EventRouter::ExtensionHasEventListener(const std::string& extension_id, |
| } |
| std::set<std::string> EventRouter::GetRegisteredEvents( |
| - const std::string& extension_id) const { |
| + const std::string& extension_id, |
| + const char* pref_key) const { |
| std::set<std::string> events; |
| const ListValue* events_value = NULL; |
| - if (!extension_prefs_ || |
| - !extension_prefs_->ReadPrefAsList( |
| - extension_id, kRegisteredEvents, &events_value)) { |
| + if (!extension_prefs_ || !extension_prefs_->ReadPrefAsList( |
| + extension_id, pref_key, &events_value)) { |
| return events; |
| } |
| @@ -342,6 +417,14 @@ std::set<std::string> EventRouter::GetRegisteredEvents( |
| return events; |
| } |
| +void EventRouter::ClearRegisteredEventsForTest( |
| + const ExtensionId& extension_id) { |
| + SetRegisteredEvents(extension_id, std::set<std::string>(), |
| + kRegisteredLazyEvents); |
| + SetRegisteredEvents(extension_id, std::set<std::string>(), |
| + kRegisteredServiceWorkerEvents); |
| +} |
| + |
| void EventRouter::RemoveFilterFromEvent(const std::string& event_name, |
| const std::string& extension_id, |
| const DictionaryValue* filter) { |
| @@ -365,10 +448,10 @@ void EventRouter::RemoveFilterFromEvent(const std::string& event_name, |
| } |
| const DictionaryValue* EventRouter::GetFilteredEvents( |
| - const std::string& extension_id) { |
| - const DictionaryValue* events = NULL; |
| - extension_prefs_->ReadPrefAsDictionary( |
| - extension_id, kFilteredEvents, &events); |
| + const std::string& extension_id, |
| + const char* pref_key) { |
| + const DictionaryValue* events = nullptr; |
| + extension_prefs_->ReadPrefAsDictionary(extension_id, pref_key, &events); |
| return events; |
| } |
| @@ -400,7 +483,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)); |
| @@ -415,7 +497,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()); |
| } |
| @@ -427,12 +510,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 */); |
| } |
| } |
| } |
| @@ -455,7 +539,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)); |
|
Devlin
2017/05/24 17:58:25
It's arguable we wouldn't need this. We could als
lazyboy
2017/05/25 01:33:43
Right now there isn't a way to send events to *all
|
| } |
| ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get(); |
| @@ -466,7 +551,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)); |
| } |
| } |
| } |
| @@ -475,6 +560,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) { |
| @@ -542,9 +628,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); |
| @@ -716,21 +803,23 @@ 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, |
| + const char* pref_key) { |
| 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, |
| + extension_prefs_->UpdateExtensionPref(extension_id, pref_key, |
| std::move(events_value)); |
| } |
| @@ -779,9 +868,11 @@ void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, |
| const Extension* extension) { |
| // Add all registered lazy listeners to our cache. |
| std::set<std::string> registered_events = |
| - GetRegisteredEvents(extension->id()); |
| + GetRegisteredEvents(extension->id(), kRegisteredLazyEvents); |
| listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); |
| - const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); |
| + // TODO(lazyboy): Load extension SW lazy events. |
| + const DictionaryValue* filtered_events = |
| + GetFilteredEvents(extension->id(), kRegisteredLazyEvents); |
| if (filtered_events) |
| listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); |
| } |