OLD | NEW |
---|---|
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 BrowserContext* context = static_cast<BrowserContext*>(browser_context_id); | 67 BrowserContext* context = static_cast<BrowserContext*>(browser_context_id); |
68 activity_monitor::OnApiEventDispatched(context, extension_id, event_name, | 68 activity_monitor::OnApiEventDispatched(context, extension_id, event_name, |
69 args); | 69 args); |
70 } | 70 } |
71 | 71 |
72 // A global identifier used to distinguish extension events. | 72 // A global identifier used to distinguish extension events. |
73 base::StaticAtomicSequenceNumber g_extension_event_id; | 73 base::StaticAtomicSequenceNumber g_extension_event_id; |
74 | 74 |
75 } // namespace | 75 } // namespace |
76 | 76 |
77 const char EventRouter::kRegisteredEvents[] = "events"; | 77 const char EventRouter::kRegisteredLazyEvents[] = "events"; |
78 const char EventRouter::kRegisteredServiceWorkerEvents[] = | |
79 "serviceworkerevents"; | |
78 | 80 |
79 // static | 81 // static |
80 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, | 82 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, |
83 int worker_thread_id, | |
81 void* browser_context_id, | 84 void* browser_context_id, |
82 const std::string& extension_id, | 85 const std::string& extension_id, |
83 int event_id, | 86 int event_id, |
84 const std::string& event_name, | 87 const std::string& event_name, |
85 ListValue* event_args, | 88 ListValue* event_args, |
86 UserGestureState user_gesture, | 89 UserGestureState user_gesture, |
87 const EventFilteringInfo& info) { | 90 const EventFilteringInfo& info) { |
88 NotifyEventDispatched(browser_context_id, extension_id, event_name, | 91 NotifyEventDispatched(browser_context_id, extension_id, event_name, |
89 *event_args); | 92 *event_args); |
90 | 93 |
91 ExtensionMsg_DispatchEvent_Params params; | 94 ExtensionMsg_DispatchEvent_Params params; |
95 params.worker_thread_id = worker_thread_id; | |
92 params.extension_id = extension_id; | 96 params.extension_id = extension_id; |
93 params.event_name = event_name; | 97 params.event_name = event_name; |
94 params.event_id = event_id; | 98 params.event_id = event_id; |
95 params.is_user_gesture = user_gesture == USER_GESTURE_ENABLED; | 99 params.is_user_gesture = user_gesture == USER_GESTURE_ENABLED; |
96 params.filtering_info.Swap(info.AsValue().get()); | 100 params.filtering_info.Swap(info.AsValue().get()); |
97 | 101 |
98 ipc_sender->Send(new ExtensionMsg_DispatchEvent(params, *event_args)); | 102 ipc_sender->Send(new ExtensionMsg_DispatchEvent(params, *event_args)); |
99 } | 103 } |
100 | 104 |
101 // static | 105 // static |
(...skipping 25 matching lines...) Expand all Loading... | |
127 } else { | 131 } else { |
128 // This is called from WebRequest API. | 132 // This is called from WebRequest API. |
129 // TODO(lazyboy): Skip this entirely: http://crbug.com/488747. | 133 // TODO(lazyboy): Skip this entirely: http://crbug.com/488747. |
130 BrowserThread::PostTask( | 134 BrowserThread::PostTask( |
131 BrowserThread::UI, FROM_HERE, | 135 BrowserThread::UI, FROM_HERE, |
132 base::Bind(&EventRouter::DoDispatchEventToSenderBookkeepingOnUI, | 136 base::Bind(&EventRouter::DoDispatchEventToSenderBookkeepingOnUI, |
133 browser_context_id, extension_id, event_id, histogram_value, | 137 browser_context_id, extension_id, event_id, histogram_value, |
134 event_name)); | 138 event_name)); |
135 } | 139 } |
136 | 140 |
137 DispatchExtensionMessage(ipc_sender, browser_context_id, extension_id, | 141 DispatchExtensionMessage(ipc_sender, |
142 // TODO(lazyboy): |kNonWorkerThreadId| means these | |
143 // will not work for extension SW. | |
144 kNonWorkerThreadId, browser_context_id, extension_id, | |
138 event_id, event_name, event_args.get(), user_gesture, | 145 event_id, event_name, event_args.get(), user_gesture, |
139 info); | 146 info); |
140 } | 147 } |
141 | 148 |
142 EventRouter::EventRouter(BrowserContext* browser_context, | 149 EventRouter::EventRouter(BrowserContext* browser_context, |
143 ExtensionPrefs* extension_prefs) | 150 ExtensionPrefs* extension_prefs) |
144 : browser_context_(browser_context), | 151 : browser_context_(browser_context), |
145 extension_prefs_(extension_prefs), | 152 extension_prefs_(extension_prefs), |
146 extension_registry_observer_(this), | 153 extension_registry_observer_(this), |
147 listeners_(this) { | 154 listeners_(this) { |
148 registrar_.Add(this, | 155 registrar_.Add(this, |
149 extensions::NOTIFICATION_EXTENSION_ENABLED, | 156 extensions::NOTIFICATION_EXTENSION_ENABLED, |
150 content::Source<BrowserContext>(browser_context_)); | 157 content::Source<BrowserContext>(browser_context_)); |
151 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); | 158 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
152 } | 159 } |
153 | 160 |
154 EventRouter::~EventRouter() { | 161 EventRouter::~EventRouter() { |
155 for (auto* process : observed_process_set_) | 162 for (auto* process : observed_process_set_) |
156 process->RemoveObserver(this); | 163 process->RemoveObserver(this); |
157 } | 164 } |
158 | 165 |
159 void EventRouter::AddEventListener(const std::string& event_name, | 166 void EventRouter::AddEventListener(const std::string& event_name, |
160 content::RenderProcessHost* process, | 167 content::RenderProcessHost* process, |
161 const std::string& extension_id) { | 168 const std::string& extension_id) { |
162 listeners_.AddListener(EventListener::ForExtension( | 169 listeners_.AddListener(EventListener::ForExtension( |
163 event_name, extension_id, process, std::unique_ptr<DictionaryValue>())); | 170 event_name, extension_id, process, std::unique_ptr<DictionaryValue>())); |
164 } | 171 } |
165 | 172 |
173 void EventRouter::AddServiceWorkerEventListener( | |
174 const std::string& event_name, | |
175 content::RenderProcessHost* process, | |
176 const ExtensionId& extension_id, | |
177 int worker_thread_id) { | |
178 listeners_.AddListener(EventListener::ForExtensionServiceWorker( | |
179 event_name, extension_id, process, worker_thread_id, | |
180 std::unique_ptr<DictionaryValue>())); | |
Devlin
2017/05/24 17:58:25
nit: could just pass nullptr
lazyboy
2017/05/25 01:33:43
Done.
| |
181 } | |
182 | |
166 void EventRouter::RemoveEventListener(const std::string& event_name, | 183 void EventRouter::RemoveEventListener(const std::string& event_name, |
167 content::RenderProcessHost* process, | 184 content::RenderProcessHost* process, |
168 const std::string& extension_id) { | 185 const std::string& extension_id) { |
169 std::unique_ptr<EventListener> listener = EventListener::ForExtension( | 186 std::unique_ptr<EventListener> listener = EventListener::ForExtension( |
170 event_name, extension_id, process, std::unique_ptr<DictionaryValue>()); | 187 event_name, extension_id, process, std::unique_ptr<DictionaryValue>()); |
171 listeners_.RemoveListener(listener.get()); | 188 listeners_.RemoveListener(listener.get()); |
172 } | 189 } |
173 | 190 |
191 void EventRouter::RemoveServiceWorkerEventListener( | |
192 const std::string& event_name, | |
193 content::RenderProcessHost* process, | |
194 const ExtensionId& extension_id, | |
195 int worker_thread_id) { | |
196 std::unique_ptr<EventListener> listener = | |
197 EventListener::ForExtensionServiceWorker( | |
198 event_name, extension_id, process, worker_thread_id, | |
199 std::unique_ptr<DictionaryValue>()); | |
200 listeners_.RemoveListener(listener.get()); | |
201 } | |
202 | |
174 void EventRouter::AddEventListenerForURL(const std::string& event_name, | 203 void EventRouter::AddEventListenerForURL(const std::string& event_name, |
175 content::RenderProcessHost* process, | 204 content::RenderProcessHost* process, |
176 const GURL& listener_url) { | 205 const GURL& listener_url) { |
177 listeners_.AddListener(EventListener::ForURL( | 206 listeners_.AddListener(EventListener::ForURL( |
178 event_name, listener_url, process, std::unique_ptr<DictionaryValue>())); | 207 event_name, listener_url, process, std::unique_ptr<DictionaryValue>())); |
179 } | 208 } |
180 | 209 |
181 void EventRouter::RemoveEventListenerForURL(const std::string& event_name, | 210 void EventRouter::RemoveEventListenerForURL(const std::string& event_name, |
182 content::RenderProcessHost* process, | 211 content::RenderProcessHost* process, |
183 const GURL& listener_url) { | 212 const GURL& listener_url) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 observed_process_set_.erase(host); | 269 observed_process_set_.erase(host); |
241 host->RemoveObserver(this); | 270 host->RemoveObserver(this); |
242 } | 271 } |
243 | 272 |
244 void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) { | 273 void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) { |
245 listeners_.RemoveListenersForProcess(host); | 274 listeners_.RemoveListenersForProcess(host); |
246 observed_process_set_.erase(host); | 275 observed_process_set_.erase(host); |
247 host->RemoveObserver(this); | 276 host->RemoveObserver(this); |
248 } | 277 } |
249 | 278 |
250 void EventRouter::AddLazyEventListener(const std::string& event_name, | 279 void EventRouter::AddLazyEventListenerImpl(const std::string& event_name, |
251 const std::string& extension_id) { | 280 const ExtensionId& extension_id, |
252 bool is_new = listeners_.AddListener(EventListener::ForExtension( | 281 int worker_thread_id) { |
253 event_name, extension_id, NULL, std::unique_ptr<DictionaryValue>())); | 282 bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId; |
283 bool is_new = listeners_.AddListener( | |
284 is_for_service_worker | |
285 ? EventListener::ForExtensionServiceWorker( | |
286 event_name, extension_id, nullptr, worker_thread_id, | |
287 std::unique_ptr<DictionaryValue>()) | |
288 : EventListener::ForExtension(event_name, extension_id, nullptr, | |
289 std::unique_ptr<DictionaryValue>())); | |
254 | 290 |
255 if (is_new) { | 291 if (is_new) { |
256 std::set<std::string> events = GetRegisteredEvents(extension_id); | 292 std::set<std::string> events = GetRegisteredEvents( |
293 extension_id, is_for_service_worker ? kRegisteredServiceWorkerEvents | |
294 : kRegisteredLazyEvents); | |
257 bool prefs_is_new = events.insert(event_name).second; | 295 bool prefs_is_new = events.insert(event_name).second; |
258 if (prefs_is_new) | 296 if (prefs_is_new) { |
259 SetRegisteredEvents(extension_id, events); | 297 SetRegisteredEvents(extension_id, events, |
298 is_for_service_worker ? kRegisteredServiceWorkerEvents | |
299 : kRegisteredLazyEvents); | |
300 } | |
260 } | 301 } |
261 } | 302 } |
262 | 303 |
263 void EventRouter::RemoveLazyEventListener(const std::string& event_name, | 304 void EventRouter::RemoveLazyEventListenerImpl(const std::string& event_name, |
264 const std::string& extension_id) { | 305 const ExtensionId& extension_id, |
265 std::unique_ptr<EventListener> listener = EventListener::ForExtension( | 306 int worker_thread_id) { |
266 event_name, extension_id, NULL, std::unique_ptr<DictionaryValue>()); | 307 bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId; |
308 std::unique_ptr<EventListener> listener = | |
309 is_for_service_worker | |
310 ? EventListener::ForExtensionServiceWorker( | |
311 event_name, extension_id, nullptr, worker_thread_id, | |
312 std::unique_ptr<DictionaryValue>()) | |
313 : EventListener::ForExtension(event_name, extension_id, nullptr, | |
314 std::unique_ptr<DictionaryValue>()); | |
267 bool did_exist = listeners_.RemoveListener(listener.get()); | 315 bool did_exist = listeners_.RemoveListener(listener.get()); |
268 | 316 |
269 if (did_exist) { | 317 if (did_exist) { |
270 std::set<std::string> events = GetRegisteredEvents(extension_id); | 318 std::set<std::string> events = |
319 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.
| |
271 bool prefs_did_exist = events.erase(event_name) > 0; | 320 bool prefs_did_exist = events.erase(event_name) > 0; |
272 DCHECK(prefs_did_exist); | 321 DCHECK(prefs_did_exist); |
273 SetRegisteredEvents(extension_id, events); | 322 SetRegisteredEvents(extension_id, events, kRegisteredLazyEvents); |
274 } | 323 } |
275 } | 324 } |
276 | 325 |
326 void EventRouter::AddLazyEventListener(const std::string& event_name, | |
327 const ExtensionId& extension_id) { | |
328 AddLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId); | |
329 } | |
330 | |
331 void EventRouter::RemoveLazyEventListener(const std::string& event_name, | |
332 const ExtensionId& extension_id) { | |
333 RemoveLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId); | |
334 } | |
335 | |
336 void EventRouter::AddLazyServiceWorkerEventListener( | |
337 const std::string& event_name, | |
338 const ExtensionId& extension_id, | |
339 int worker_thread_id) { | |
340 AddLazyEventListenerImpl(event_name, extension_id, worker_thread_id); | |
341 } | |
342 | |
343 void EventRouter::RemoveLazyServiceWorkerEventListener( | |
344 const std::string& event_name, | |
345 const ExtensionId& extension_id, | |
346 int worker_thread_id) { | |
347 RemoveLazyEventListenerImpl(event_name, extension_id, worker_thread_id); | |
348 } | |
349 | |
350 // TODO(lazyboy): Support filters for extension SW events. | |
277 void EventRouter::AddFilteredEventListener(const std::string& event_name, | 351 void EventRouter::AddFilteredEventListener(const std::string& event_name, |
278 content::RenderProcessHost* process, | 352 content::RenderProcessHost* process, |
279 const std::string& extension_id, | 353 const std::string& extension_id, |
280 const base::DictionaryValue& filter, | 354 const base::DictionaryValue& filter, |
281 bool add_lazy_listener) { | 355 bool add_lazy_listener) { |
282 listeners_.AddListener(EventListener::ForExtension( | 356 listeners_.AddListener(EventListener::ForExtension( |
283 event_name, extension_id, process, | 357 event_name, extension_id, process, |
284 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); | 358 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
285 | 359 |
286 if (add_lazy_listener) { | 360 if (add_lazy_listener) { |
287 bool added = listeners_.AddListener(EventListener::ForExtension( | 361 bool added = listeners_.AddListener(EventListener::ForExtension( |
288 event_name, extension_id, NULL, | 362 event_name, extension_id, nullptr, |
289 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); | 363 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
290 | 364 |
291 if (added) | 365 if (added) |
292 AddFilterToEvent(event_name, extension_id, &filter); | 366 AddFilterToEvent(event_name, extension_id, &filter); |
293 } | 367 } |
294 } | 368 } |
295 | 369 |
370 // TODO(lazyboy): Support filters for extension SW events. | |
296 void EventRouter::RemoveFilteredEventListener( | 371 void EventRouter::RemoveFilteredEventListener( |
297 const std::string& event_name, | 372 const std::string& event_name, |
298 content::RenderProcessHost* process, | 373 content::RenderProcessHost* process, |
299 const std::string& extension_id, | 374 const std::string& extension_id, |
300 const base::DictionaryValue& filter, | 375 const base::DictionaryValue& filter, |
301 bool remove_lazy_listener) { | 376 bool remove_lazy_listener) { |
302 std::unique_ptr<EventListener> listener = EventListener::ForExtension( | 377 std::unique_ptr<EventListener> listener = EventListener::ForExtension( |
303 event_name, extension_id, process, | 378 event_name, extension_id, process, |
304 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); | 379 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); |
305 | 380 |
(...skipping 11 matching lines...) Expand all Loading... | |
317 bool EventRouter::HasEventListener(const std::string& event_name) { | 392 bool EventRouter::HasEventListener(const std::string& event_name) { |
318 return listeners_.HasListenerForEvent(event_name); | 393 return listeners_.HasListenerForEvent(event_name); |
319 } | 394 } |
320 | 395 |
321 bool EventRouter::ExtensionHasEventListener(const std::string& extension_id, | 396 bool EventRouter::ExtensionHasEventListener(const std::string& extension_id, |
322 const std::string& event_name) { | 397 const std::string& event_name) { |
323 return listeners_.HasListenerForExtension(extension_id, event_name); | 398 return listeners_.HasListenerForExtension(extension_id, event_name); |
324 } | 399 } |
325 | 400 |
326 std::set<std::string> EventRouter::GetRegisteredEvents( | 401 std::set<std::string> EventRouter::GetRegisteredEvents( |
327 const std::string& extension_id) const { | 402 const std::string& extension_id, |
403 const char* pref_key) const { | |
328 std::set<std::string> events; | 404 std::set<std::string> events; |
329 const ListValue* events_value = NULL; | 405 const ListValue* events_value = NULL; |
330 | 406 |
331 if (!extension_prefs_ || | 407 if (!extension_prefs_ || !extension_prefs_->ReadPrefAsList( |
332 !extension_prefs_->ReadPrefAsList( | 408 extension_id, pref_key, &events_value)) { |
333 extension_id, kRegisteredEvents, &events_value)) { | |
334 return events; | 409 return events; |
335 } | 410 } |
336 | 411 |
337 for (size_t i = 0; i < events_value->GetSize(); ++i) { | 412 for (size_t i = 0; i < events_value->GetSize(); ++i) { |
338 std::string event; | 413 std::string event; |
339 if (events_value->GetString(i, &event)) | 414 if (events_value->GetString(i, &event)) |
340 events.insert(event); | 415 events.insert(event); |
341 } | 416 } |
342 return events; | 417 return events; |
343 } | 418 } |
344 | 419 |
420 void EventRouter::ClearRegisteredEventsForTest( | |
421 const ExtensionId& extension_id) { | |
422 SetRegisteredEvents(extension_id, std::set<std::string>(), | |
423 kRegisteredLazyEvents); | |
424 SetRegisteredEvents(extension_id, std::set<std::string>(), | |
425 kRegisteredServiceWorkerEvents); | |
426 } | |
427 | |
345 void EventRouter::RemoveFilterFromEvent(const std::string& event_name, | 428 void EventRouter::RemoveFilterFromEvent(const std::string& event_name, |
346 const std::string& extension_id, | 429 const std::string& extension_id, |
347 const DictionaryValue* filter) { | 430 const DictionaryValue* filter) { |
348 ExtensionPrefs::ScopedDictionaryUpdate update( | 431 ExtensionPrefs::ScopedDictionaryUpdate update( |
349 extension_prefs_, extension_id, kFilteredEvents); | 432 extension_prefs_, extension_id, kFilteredEvents); |
350 DictionaryValue* filtered_events = update.Get(); | 433 DictionaryValue* filtered_events = update.Get(); |
351 ListValue* filter_list = NULL; | 434 ListValue* filter_list = NULL; |
352 if (!filtered_events || | 435 if (!filtered_events || |
353 !filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { | 436 !filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { |
354 return; | 437 return; |
355 } | 438 } |
356 | 439 |
357 for (size_t i = 0; i < filter_list->GetSize(); i++) { | 440 for (size_t i = 0; i < filter_list->GetSize(); i++) { |
358 DictionaryValue* filter_value = nullptr; | 441 DictionaryValue* filter_value = nullptr; |
359 CHECK(filter_list->GetDictionary(i, &filter_value)); | 442 CHECK(filter_list->GetDictionary(i, &filter_value)); |
360 if (filter_value->Equals(filter)) { | 443 if (filter_value->Equals(filter)) { |
361 filter_list->Remove(i, nullptr); | 444 filter_list->Remove(i, nullptr); |
362 break; | 445 break; |
363 } | 446 } |
364 } | 447 } |
365 } | 448 } |
366 | 449 |
367 const DictionaryValue* EventRouter::GetFilteredEvents( | 450 const DictionaryValue* EventRouter::GetFilteredEvents( |
368 const std::string& extension_id) { | 451 const std::string& extension_id, |
369 const DictionaryValue* events = NULL; | 452 const char* pref_key) { |
370 extension_prefs_->ReadPrefAsDictionary( | 453 const DictionaryValue* events = nullptr; |
371 extension_id, kFilteredEvents, &events); | 454 extension_prefs_->ReadPrefAsDictionary(extension_id, pref_key, &events); |
372 return events; | 455 return events; |
373 } | 456 } |
374 | 457 |
375 void EventRouter::BroadcastEvent(std::unique_ptr<Event> event) { | 458 void EventRouter::BroadcastEvent(std::unique_ptr<Event> event) { |
376 DispatchEventImpl(std::string(), linked_ptr<Event>(event.release())); | 459 DispatchEventImpl(std::string(), linked_ptr<Event>(event.release())); |
377 } | 460 } |
378 | 461 |
379 void EventRouter::DispatchEventToExtension(const std::string& extension_id, | 462 void EventRouter::DispatchEventToExtension(const std::string& extension_id, |
380 std::unique_ptr<Event> event) { | 463 std::unique_ptr<Event> event) { |
381 DCHECK(!extension_id.empty()); | 464 DCHECK(!extension_id.empty()); |
(...skipping 11 matching lines...) Expand all Loading... | |
393 if (!has_listener) | 476 if (!has_listener) |
394 RemoveLazyEventListener(event_name, extension_id); | 477 RemoveLazyEventListener(event_name, extension_id); |
395 } | 478 } |
396 | 479 |
397 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, | 480 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, |
398 const linked_ptr<Event>& event) { | 481 const linked_ptr<Event>& event) { |
399 // We don't expect to get events from a completely different browser context. | 482 // We don't expect to get events from a completely different browser context. |
400 DCHECK(!event->restrict_to_browser_context || | 483 DCHECK(!event->restrict_to_browser_context || |
401 ExtensionsBrowserClient::Get()->IsSameContext( | 484 ExtensionsBrowserClient::Get()->IsSameContext( |
402 browser_context_, event->restrict_to_browser_context)); | 485 browser_context_, event->restrict_to_browser_context)); |
403 | |
404 std::set<const EventListener*> listeners( | 486 std::set<const EventListener*> listeners( |
405 listeners_.GetEventListeners(*event)); | 487 listeners_.GetEventListeners(*event)); |
406 | 488 |
407 std::set<EventDispatchIdentifier> already_dispatched; | 489 std::set<EventDispatchIdentifier> already_dispatched; |
408 | 490 |
409 // We dispatch events for lazy background pages first because attempting to do | 491 // We dispatch events for lazy background pages first because attempting to do |
410 // so will cause those that are being suspended to cancel that suspension. | 492 // so will cause those that are being suspended to cancel that suspension. |
411 // As canceling a suspension entails sending an event to the affected | 493 // As canceling a suspension entails sending an event to the affected |
412 // background page, and as that event needs to be delivered before we dispatch | 494 // background page, and as that event needs to be delivered before we dispatch |
413 // the event we are dispatching here, we dispatch to the lazy listeners here | 495 // the event we are dispatching here, we dispatch to the lazy listeners here |
414 // first. | 496 // first. |
415 for (const EventListener* listener : listeners) { | 497 for (const EventListener* listener : listeners) { |
416 if (restrict_to_extension_id.empty() || | 498 if (restrict_to_extension_id.empty() || |
417 restrict_to_extension_id == listener->extension_id()) { | 499 restrict_to_extension_id == listener->extension_id()) { |
418 if (listener->IsLazy()) { | 500 // TODO(lazyboy): Support lazy listeners for extension SW events. |
501 if (listener->IsLazy() && !listener->IsForServiceWorker()) { | |
419 DispatchLazyEvent(listener->extension_id(), event, &already_dispatched, | 502 DispatchLazyEvent(listener->extension_id(), event, &already_dispatched, |
420 listener->filter()); | 503 listener->filter()); |
421 } | 504 } |
422 } | 505 } |
423 } | 506 } |
424 | 507 |
425 for (const EventListener* listener : listeners) { | 508 for (const EventListener* listener : listeners) { |
426 if (restrict_to_extension_id.empty() || | 509 if (restrict_to_extension_id.empty() || |
427 restrict_to_extension_id == listener->extension_id()) { | 510 restrict_to_extension_id == listener->extension_id()) { |
428 if (listener->process()) { | 511 if (listener->process()) { |
429 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), | 512 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), |
430 listener->extension_id()); | 513 listener->extension_id(), |
514 listener->worker_thread_id()); | |
431 if (!base::ContainsKey(already_dispatched, dispatch_id)) { | 515 if (!base::ContainsKey(already_dispatched, dispatch_id)) { |
432 DispatchEventToProcess(listener->extension_id(), | 516 DispatchEventToProcess(listener->extension_id(), |
433 listener->listener_url(), listener->process(), | 517 listener->listener_url(), listener->process(), |
434 event, listener->filter(), | 518 listener->worker_thread_id(), event, |
435 false /* did_enqueue */); | 519 listener->filter(), false /* did_enqueue */); |
436 } | 520 } |
437 } | 521 } |
438 } | 522 } |
439 } | 523 } |
440 } | 524 } |
441 | 525 |
442 void EventRouter::DispatchLazyEvent( | 526 void EventRouter::DispatchLazyEvent( |
443 const std::string& extension_id, | 527 const std::string& extension_id, |
444 const linked_ptr<Event>& event, | 528 const linked_ptr<Event>& event, |
445 std::set<EventDispatchIdentifier>* already_dispatched, | 529 std::set<EventDispatchIdentifier>* already_dispatched, |
446 const base::DictionaryValue* listener_filter) { | 530 const base::DictionaryValue* listener_filter) { |
447 // Check both the original and the incognito browser context to see if we | 531 // Check both the original and the incognito browser context to see if we |
448 // should load a lazy bg page to handle the event. The latter case | 532 // should load a lazy bg page to handle the event. The latter case |
449 // occurs in the case of split-mode extensions. | 533 // occurs in the case of split-mode extensions. |
450 const Extension* extension = | 534 const Extension* extension = |
451 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( | 535 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( |
452 extension_id); | 536 extension_id); |
453 if (!extension) | 537 if (!extension) |
454 return; | 538 return; |
455 | 539 |
456 if (MaybeLoadLazyBackgroundPageToDispatchEvent(browser_context_, extension, | 540 if (MaybeLoadLazyBackgroundPageToDispatchEvent(browser_context_, extension, |
457 event, listener_filter)) { | 541 event, listener_filter)) { |
458 already_dispatched->insert(std::make_pair(browser_context_, extension_id)); | 542 already_dispatched->insert( |
543 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
| |
459 } | 544 } |
460 | 545 |
461 ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get(); | 546 ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get(); |
462 if (browser_client->HasOffTheRecordContext(browser_context_) && | 547 if (browser_client->HasOffTheRecordContext(browser_context_) && |
463 IncognitoInfo::IsSplitMode(extension)) { | 548 IncognitoInfo::IsSplitMode(extension)) { |
464 BrowserContext* incognito_context = | 549 BrowserContext* incognito_context = |
465 browser_client->GetOffTheRecordContext(browser_context_); | 550 browser_client->GetOffTheRecordContext(browser_context_); |
466 if (MaybeLoadLazyBackgroundPageToDispatchEvent(incognito_context, extension, | 551 if (MaybeLoadLazyBackgroundPageToDispatchEvent(incognito_context, extension, |
467 event, listener_filter)) { | 552 event, listener_filter)) { |
468 already_dispatched->insert( | 553 already_dispatched->insert( |
469 std::make_pair(incognito_context, extension_id)); | 554 std::make_tuple(incognito_context, extension_id, kNonWorkerThreadId)); |
470 } | 555 } |
471 } | 556 } |
472 } | 557 } |
473 | 558 |
474 void EventRouter::DispatchEventToProcess( | 559 void EventRouter::DispatchEventToProcess( |
475 const std::string& extension_id, | 560 const std::string& extension_id, |
476 const GURL& listener_url, | 561 const GURL& listener_url, |
477 content::RenderProcessHost* process, | 562 content::RenderProcessHost* process, |
563 int worker_thread_id, | |
478 const linked_ptr<Event>& event, | 564 const linked_ptr<Event>& event, |
479 const base::DictionaryValue* listener_filter, | 565 const base::DictionaryValue* listener_filter, |
480 bool did_enqueue) { | 566 bool did_enqueue) { |
481 BrowserContext* listener_context = process->GetBrowserContext(); | 567 BrowserContext* listener_context = process->GetBrowserContext(); |
482 ProcessMap* process_map = ProcessMap::Get(listener_context); | 568 ProcessMap* process_map = ProcessMap::Get(listener_context); |
483 | 569 |
484 // NOTE: |extension| being NULL does not necessarily imply that this event | 570 // NOTE: |extension| being NULL does not necessarily imply that this event |
485 // shouldn't be dispatched. Events can be dispatched to WebUI and webviews as | 571 // shouldn't be dispatched. Events can be dispatched to WebUI and webviews as |
486 // well. It all depends on what GetMostLikelyContextType returns. | 572 // well. It all depends on what GetMostLikelyContextType returns. |
487 const Extension* extension = | 573 const Extension* extension = |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
535 return; | 621 return; |
536 } | 622 } |
537 | 623 |
538 if (!event->will_dispatch_callback.is_null() && | 624 if (!event->will_dispatch_callback.is_null() && |
539 !event->will_dispatch_callback.Run(listener_context, extension, | 625 !event->will_dispatch_callback.Run(listener_context, extension, |
540 event.get(), listener_filter)) { | 626 event.get(), listener_filter)) { |
541 return; | 627 return; |
542 } | 628 } |
543 | 629 |
544 int event_id = g_extension_event_id.GetNext(); | 630 int event_id = g_extension_event_id.GetNext(); |
545 DispatchExtensionMessage(process, listener_context, extension_id, event_id, | 631 DispatchExtensionMessage(process, worker_thread_id, listener_context, |
546 event->event_name, event->event_args.get(), | 632 extension_id, event_id, event->event_name, |
547 event->user_gesture, event->filter_info); | 633 event->event_args.get(), event->user_gesture, |
634 event->filter_info); | |
548 | 635 |
549 if (extension) { | 636 if (extension) { |
550 ReportEvent(event->histogram_value, extension, did_enqueue); | 637 ReportEvent(event->histogram_value, extension, did_enqueue); |
551 IncrementInFlightEvents(listener_context, extension, event_id, | 638 IncrementInFlightEvents(listener_context, extension, event_id, |
552 event->event_name); | 639 event->event_name); |
553 } | 640 } |
554 } | 641 } |
555 | 642 |
556 bool EventRouter::CanDispatchEventToBrowserContext( | 643 bool EventRouter::CanDispatchEventToBrowserContext( |
557 BrowserContext* context, | 644 BrowserContext* context, |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 } | 796 } |
710 } | 797 } |
711 } | 798 } |
712 | 799 |
713 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, | 800 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, |
714 ExtensionHost* host) { | 801 ExtensionHost* host) { |
715 if (!host) | 802 if (!host) |
716 return; | 803 return; |
717 | 804 |
718 if (listeners_.HasProcessListener(host->render_process_host(), | 805 if (listeners_.HasProcessListener(host->render_process_host(), |
806 kNonWorkerThreadId, | |
719 host->extension()->id())) { | 807 host->extension()->id())) { |
720 DispatchEventToProcess(host->extension()->id(), host->GetURL(), | 808 DispatchEventToProcess(host->extension()->id(), host->GetURL(), |
721 host->render_process_host(), event, nullptr, | 809 host->render_process_host(), kNonWorkerThreadId, |
722 true /* did_enqueue */); | 810 event, nullptr, true /* did_enqueue */); |
723 } | 811 } |
724 } | 812 } |
725 | 813 |
726 void EventRouter::SetRegisteredEvents(const std::string& extension_id, | 814 void EventRouter::SetRegisteredEvents(const std::string& extension_id, |
727 const std::set<std::string>& events) { | 815 const std::set<std::string>& events, |
816 const char* pref_key) { | |
728 auto events_value = base::MakeUnique<base::ListValue>(); | 817 auto events_value = base::MakeUnique<base::ListValue>(); |
729 for (std::set<std::string>::const_iterator iter = events.begin(); | 818 for (std::set<std::string>::const_iterator iter = events.begin(); |
730 iter != events.end(); ++iter) { | 819 iter != events.end(); ++iter) { |
731 events_value->AppendString(*iter); | 820 events_value->AppendString(*iter); |
732 } | 821 } |
733 extension_prefs_->UpdateExtensionPref(extension_id, kRegisteredEvents, | 822 extension_prefs_->UpdateExtensionPref(extension_id, pref_key, |
734 std::move(events_value)); | 823 std::move(events_value)); |
735 } | 824 } |
736 | 825 |
737 void EventRouter::AddFilterToEvent(const std::string& event_name, | 826 void EventRouter::AddFilterToEvent(const std::string& event_name, |
738 const std::string& extension_id, | 827 const std::string& extension_id, |
739 const DictionaryValue* filter) { | 828 const DictionaryValue* filter) { |
740 ExtensionPrefs::ScopedDictionaryUpdate update(extension_prefs_, extension_id, | 829 ExtensionPrefs::ScopedDictionaryUpdate update(extension_prefs_, extension_id, |
741 kFilteredEvents); | 830 kFilteredEvents); |
742 DictionaryValue* filtered_events = update.Get(); | 831 DictionaryValue* filtered_events = update.Get(); |
743 if (!filtered_events) | 832 if (!filtered_events) |
(...skipping 28 matching lines...) Expand all Loading... | |
772 } | 861 } |
773 default: | 862 default: |
774 NOTREACHED(); | 863 NOTREACHED(); |
775 } | 864 } |
776 } | 865 } |
777 | 866 |
778 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, | 867 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, |
779 const Extension* extension) { | 868 const Extension* extension) { |
780 // Add all registered lazy listeners to our cache. | 869 // Add all registered lazy listeners to our cache. |
781 std::set<std::string> registered_events = | 870 std::set<std::string> registered_events = |
782 GetRegisteredEvents(extension->id()); | 871 GetRegisteredEvents(extension->id(), kRegisteredLazyEvents); |
783 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); | 872 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); |
784 const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); | 873 // TODO(lazyboy): Load extension SW lazy events. |
874 const DictionaryValue* filtered_events = | |
875 GetFilteredEvents(extension->id(), kRegisteredLazyEvents); | |
785 if (filtered_events) | 876 if (filtered_events) |
786 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); | 877 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); |
787 } | 878 } |
788 | 879 |
789 void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context, | 880 void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context, |
790 const Extension* extension, | 881 const Extension* extension, |
791 UnloadedExtensionReason reason) { | 882 UnloadedExtensionReason reason) { |
792 // Remove all registered listeners from our cache. | 883 // Remove all registered listeners from our cache. |
793 listeners_.RemoveListenersForExtension(extension->id()); | 884 listeners_.RemoveListenersForExtension(extension->id()); |
794 } | 885 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
848 const std::string& extension_id, | 939 const std::string& extension_id, |
849 const GURL& listener_url, | 940 const GURL& listener_url, |
850 content::BrowserContext* browser_context) | 941 content::BrowserContext* browser_context) |
851 : event_name(event_name), | 942 : event_name(event_name), |
852 extension_id(extension_id), | 943 extension_id(extension_id), |
853 listener_url(listener_url), | 944 listener_url(listener_url), |
854 browser_context(browser_context) { | 945 browser_context(browser_context) { |
855 } | 946 } |
856 | 947 |
857 } // namespace extensions | 948 } // namespace extensions |
OLD | NEW |