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); |