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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 BrowserContext* context = static_cast<BrowserContext*>(browser_context_id); | 61 BrowserContext* context = static_cast<BrowserContext*>(browser_context_id); |
62 activity_monitor::OnApiEventDispatched(context, extension_id, event_name, | 62 activity_monitor::OnApiEventDispatched(context, extension_id, event_name, |
63 args); | 63 args); |
64 } | 64 } |
65 | 65 |
66 // A global identifier used to distinguish extension events. | 66 // A global identifier used to distinguish extension events. |
67 base::StaticAtomicSequenceNumber g_extension_event_id; | 67 base::StaticAtomicSequenceNumber g_extension_event_id; |
68 | 68 |
69 } // namespace | 69 } // namespace |
70 | 70 |
71 const char EventRouter::kRegisteredEvents[] = "events"; | 71 const char EventRouter::kRegisteredLazyEvents[] = "events"; |
| 72 const char EventRouter::kRegisteredServiceWorkerEvents[] = |
| 73 "serviceworkerevents"; |
72 | 74 |
73 // static | 75 // static |
74 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, | 76 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, |
| 77 int worker_thread_id, |
75 void* browser_context_id, | 78 void* browser_context_id, |
76 const std::string& extension_id, | 79 const std::string& extension_id, |
77 int event_id, | 80 int event_id, |
78 const std::string& event_name, | 81 const std::string& event_name, |
79 ListValue* event_args, | 82 ListValue* event_args, |
80 UserGestureState user_gesture, | 83 UserGestureState user_gesture, |
81 const EventFilteringInfo& info) { | 84 const EventFilteringInfo& info) { |
82 NotifyEventDispatched(browser_context_id, extension_id, event_name, | 85 NotifyEventDispatched(browser_context_id, extension_id, event_name, |
83 *event_args); | 86 *event_args); |
84 | 87 |
85 ExtensionMsg_DispatchEvent_Params params; | 88 ExtensionMsg_DispatchEvent_Params params; |
| 89 params.worker_thread_id = worker_thread_id; |
86 params.extension_id = extension_id; | 90 params.extension_id = extension_id; |
87 params.event_name = event_name; | 91 params.event_name = event_name; |
88 params.event_id = event_id; | 92 params.event_id = event_id; |
89 params.is_user_gesture = user_gesture == USER_GESTURE_ENABLED; | 93 params.is_user_gesture = user_gesture == USER_GESTURE_ENABLED; |
90 params.filtering_info.Swap(info.AsValue().get()); | 94 params.filtering_info.Swap(info.AsValue().get()); |
91 | 95 |
92 ipc_sender->Send(new ExtensionMsg_DispatchEvent(params, *event_args)); | 96 ipc_sender->Send(new ExtensionMsg_DispatchEvent(params, *event_args)); |
93 } | 97 } |
94 | 98 |
95 // static | 99 // static |
(...skipping 25 matching lines...) Expand all Loading... |
121 } else { | 125 } else { |
122 // This is called from WebRequest API. | 126 // This is called from WebRequest API. |
123 // TODO(lazyboy): Skip this entirely: http://crbug.com/488747. | 127 // TODO(lazyboy): Skip this entirely: http://crbug.com/488747. |
124 BrowserThread::PostTask( | 128 BrowserThread::PostTask( |
125 BrowserThread::UI, FROM_HERE, | 129 BrowserThread::UI, FROM_HERE, |
126 base::Bind(&EventRouter::DoDispatchEventToSenderBookkeepingOnUI, | 130 base::Bind(&EventRouter::DoDispatchEventToSenderBookkeepingOnUI, |
127 browser_context_id, extension_id, event_id, histogram_value, | 131 browser_context_id, extension_id, event_id, histogram_value, |
128 event_name)); | 132 event_name)); |
129 } | 133 } |
130 | 134 |
131 DispatchExtensionMessage(ipc_sender, browser_context_id, extension_id, | 135 DispatchExtensionMessage(ipc_sender, |
| 136 // TODO(lazyboy): |kNonWorkerThreadId| means these |
| 137 // will not work for extension SW. |
| 138 kNonWorkerThreadId, browser_context_id, extension_id, |
132 event_id, event_name, event_args.get(), user_gesture, | 139 event_id, event_name, event_args.get(), user_gesture, |
133 info); | 140 info); |
134 } | 141 } |
135 | 142 |
136 EventRouter::EventRouter(BrowserContext* browser_context, | 143 EventRouter::EventRouter(BrowserContext* browser_context, |
137 ExtensionPrefs* extension_prefs) | 144 ExtensionPrefs* extension_prefs) |
138 : browser_context_(browser_context), | 145 : browser_context_(browser_context), |
139 extension_prefs_(extension_prefs), | 146 extension_prefs_(extension_prefs), |
140 extension_registry_observer_(this), | 147 extension_registry_observer_(this), |
141 listeners_(this), | 148 listeners_(this), |
142 lazy_event_dispatch_util_(browser_context_) { | 149 lazy_event_dispatch_util_(browser_context_) { |
143 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); | 150 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
144 } | 151 } |
145 | 152 |
146 EventRouter::~EventRouter() { | 153 EventRouter::~EventRouter() { |
147 for (auto* process : observed_process_set_) | 154 for (auto* process : observed_process_set_) |
148 process->RemoveObserver(this); | 155 process->RemoveObserver(this); |
149 } | 156 } |
150 | 157 |
151 void EventRouter::AddEventListener(const std::string& event_name, | 158 void EventRouter::AddEventListener(const std::string& event_name, |
152 content::RenderProcessHost* process, | 159 content::RenderProcessHost* process, |
153 const std::string& extension_id) { | 160 const std::string& extension_id) { |
154 listeners_.AddListener(EventListener::ForExtension( | 161 listeners_.AddListener( |
155 event_name, extension_id, process, std::unique_ptr<DictionaryValue>())); | 162 EventListener::ForExtension(event_name, extension_id, process, nullptr)); |
| 163 } |
| 164 |
| 165 void EventRouter::AddServiceWorkerEventListener( |
| 166 const std::string& event_name, |
| 167 content::RenderProcessHost* process, |
| 168 const ExtensionId& extension_id, |
| 169 int worker_thread_id) { |
| 170 listeners_.AddListener(EventListener::ForExtensionServiceWorker( |
| 171 event_name, extension_id, process, worker_thread_id, nullptr)); |
156 } | 172 } |
157 | 173 |
158 void EventRouter::RemoveEventListener(const std::string& event_name, | 174 void EventRouter::RemoveEventListener(const std::string& event_name, |
159 content::RenderProcessHost* process, | 175 content::RenderProcessHost* process, |
160 const std::string& extension_id) { | 176 const std::string& extension_id) { |
161 std::unique_ptr<EventListener> listener = EventListener::ForExtension( | 177 std::unique_ptr<EventListener> listener = |
162 event_name, extension_id, process, std::unique_ptr<DictionaryValue>()); | 178 EventListener::ForExtension(event_name, extension_id, process, nullptr); |
| 179 listeners_.RemoveListener(listener.get()); |
| 180 } |
| 181 |
| 182 void EventRouter::RemoveServiceWorkerEventListener( |
| 183 const std::string& event_name, |
| 184 content::RenderProcessHost* process, |
| 185 const ExtensionId& extension_id, |
| 186 int worker_thread_id) { |
| 187 std::unique_ptr<EventListener> listener = |
| 188 EventListener::ForExtensionServiceWorker( |
| 189 event_name, extension_id, process, worker_thread_id, nullptr); |
163 listeners_.RemoveListener(listener.get()); | 190 listeners_.RemoveListener(listener.get()); |
164 } | 191 } |
165 | 192 |
166 void EventRouter::AddEventListenerForURL(const std::string& event_name, | 193 void EventRouter::AddEventListenerForURL(const std::string& event_name, |
167 content::RenderProcessHost* process, | 194 content::RenderProcessHost* process, |
168 const GURL& listener_url) { | 195 const GURL& listener_url) { |
169 listeners_.AddListener(EventListener::ForURL( | 196 listeners_.AddListener( |
170 event_name, listener_url, process, std::unique_ptr<DictionaryValue>())); | 197 EventListener::ForURL(event_name, listener_url, process, nullptr)); |
171 } | 198 } |
172 | 199 |
173 void EventRouter::RemoveEventListenerForURL(const std::string& event_name, | 200 void EventRouter::RemoveEventListenerForURL(const std::string& event_name, |
174 content::RenderProcessHost* process, | 201 content::RenderProcessHost* process, |
175 const GURL& listener_url) { | 202 const GURL& listener_url) { |
176 std::unique_ptr<EventListener> listener = EventListener::ForURL( | 203 std::unique_ptr<EventListener> listener = |
177 event_name, listener_url, process, std::unique_ptr<DictionaryValue>()); | 204 EventListener::ForURL(event_name, listener_url, process, nullptr); |
178 listeners_.RemoveListener(listener.get()); | 205 listeners_.RemoveListener(listener.get()); |
179 } | 206 } |
180 | 207 |
181 void EventRouter::RegisterObserver(Observer* observer, | 208 void EventRouter::RegisterObserver(Observer* observer, |
182 const std::string& event_name) { | 209 const std::string& event_name) { |
183 // Observing sub-event names like "foo.onBar/123" is not allowed. | 210 // Observing sub-event names like "foo.onBar/123" is not allowed. |
184 DCHECK(event_name.find('/') == std::string::npos); | 211 DCHECK(event_name.find('/') == std::string::npos); |
185 observers_[event_name] = observer; | 212 observers_[event_name] = observer; |
186 } | 213 } |
187 | 214 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 host->RemoveObserver(this); | 258 host->RemoveObserver(this); |
232 } | 259 } |
233 | 260 |
234 void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) { | 261 void EventRouter::RenderProcessHostDestroyed(content::RenderProcessHost* host) { |
235 listeners_.RemoveListenersForProcess(host); | 262 listeners_.RemoveListenersForProcess(host); |
236 observed_process_set_.erase(host); | 263 observed_process_set_.erase(host); |
237 host->RemoveObserver(this); | 264 host->RemoveObserver(this); |
238 } | 265 } |
239 | 266 |
240 void EventRouter::AddLazyEventListener(const std::string& event_name, | 267 void EventRouter::AddLazyEventListener(const std::string& event_name, |
241 const std::string& extension_id) { | 268 const ExtensionId& extension_id) { |
242 bool is_new = listeners_.AddListener(EventListener::ForExtension( | 269 AddLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId); |
243 event_name, extension_id, NULL, std::unique_ptr<DictionaryValue>())); | |
244 | |
245 if (is_new) { | |
246 std::set<std::string> events = GetRegisteredEvents(extension_id); | |
247 bool prefs_is_new = events.insert(event_name).second; | |
248 if (prefs_is_new) | |
249 SetRegisteredEvents(extension_id, events); | |
250 } | |
251 } | 270 } |
252 | 271 |
253 void EventRouter::RemoveLazyEventListener(const std::string& event_name, | 272 void EventRouter::RemoveLazyEventListener(const std::string& event_name, |
254 const std::string& extension_id) { | 273 const ExtensionId& extension_id) { |
255 std::unique_ptr<EventListener> listener = EventListener::ForExtension( | 274 RemoveLazyEventListenerImpl(event_name, extension_id, kNonWorkerThreadId); |
256 event_name, extension_id, NULL, std::unique_ptr<DictionaryValue>()); | |
257 bool did_exist = listeners_.RemoveListener(listener.get()); | |
258 | |
259 if (did_exist) { | |
260 std::set<std::string> events = GetRegisteredEvents(extension_id); | |
261 bool prefs_did_exist = events.erase(event_name) > 0; | |
262 DCHECK(prefs_did_exist); | |
263 SetRegisteredEvents(extension_id, events); | |
264 } | |
265 } | 275 } |
266 | 276 |
| 277 void EventRouter::AddLazyServiceWorkerEventListener( |
| 278 const std::string& event_name, |
| 279 const ExtensionId& extension_id, |
| 280 int worker_thread_id) { |
| 281 AddLazyEventListenerImpl(event_name, extension_id, worker_thread_id); |
| 282 } |
| 283 |
| 284 void EventRouter::RemoveLazyServiceWorkerEventListener( |
| 285 const std::string& event_name, |
| 286 const ExtensionId& extension_id, |
| 287 int worker_thread_id) { |
| 288 RemoveLazyEventListenerImpl(event_name, extension_id, worker_thread_id); |
| 289 } |
| 290 |
| 291 // TODO(lazyboy): Support filters for extension SW events. |
267 void EventRouter::AddFilteredEventListener(const std::string& event_name, | 292 void EventRouter::AddFilteredEventListener(const std::string& event_name, |
268 content::RenderProcessHost* process, | 293 content::RenderProcessHost* process, |
269 const std::string& extension_id, | 294 const std::string& extension_id, |
270 const base::DictionaryValue& filter, | 295 const base::DictionaryValue& filter, |
271 bool add_lazy_listener) { | 296 bool add_lazy_listener) { |
272 listeners_.AddListener(EventListener::ForExtension( | 297 listeners_.AddListener(EventListener::ForExtension( |
273 event_name, extension_id, process, | 298 event_name, extension_id, process, |
274 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); | 299 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
275 | 300 |
276 if (!add_lazy_listener) | 301 if (!add_lazy_listener) |
277 return; | 302 return; |
278 | 303 |
279 bool added = listeners_.AddListener(EventListener::ForExtension( | 304 bool added = listeners_.AddListener(EventListener::ForExtension( |
280 event_name, extension_id, nullptr, | 305 event_name, extension_id, nullptr, |
281 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); | 306 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
282 if (added) | 307 if (added) |
283 AddFilterToEvent(event_name, extension_id, &filter); | 308 AddFilterToEvent(event_name, extension_id, &filter); |
284 } | 309 } |
285 | 310 |
| 311 // TODO(lazyboy): Support filters for extension SW events. |
286 void EventRouter::RemoveFilteredEventListener( | 312 void EventRouter::RemoveFilteredEventListener( |
287 const std::string& event_name, | 313 const std::string& event_name, |
288 content::RenderProcessHost* process, | 314 content::RenderProcessHost* process, |
289 const std::string& extension_id, | 315 const std::string& extension_id, |
290 const base::DictionaryValue& filter, | 316 const base::DictionaryValue& filter, |
291 bool remove_lazy_listener) { | 317 bool remove_lazy_listener) { |
292 std::unique_ptr<EventListener> listener = EventListener::ForExtension( | 318 std::unique_ptr<EventListener> listener = EventListener::ForExtension( |
293 event_name, extension_id, process, | 319 event_name, extension_id, process, |
294 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); | 320 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); |
295 | 321 |
(...skipping 12 matching lines...) Expand all Loading... |
308 return listeners_.HasListenerForEvent(event_name); | 334 return listeners_.HasListenerForEvent(event_name); |
309 } | 335 } |
310 | 336 |
311 bool EventRouter::ExtensionHasEventListener( | 337 bool EventRouter::ExtensionHasEventListener( |
312 const std::string& extension_id, | 338 const std::string& extension_id, |
313 const std::string& event_name) const { | 339 const std::string& event_name) const { |
314 return listeners_.HasListenerForExtension(extension_id, event_name); | 340 return listeners_.HasListenerForExtension(extension_id, event_name); |
315 } | 341 } |
316 | 342 |
317 std::set<std::string> EventRouter::GetRegisteredEvents( | 343 std::set<std::string> EventRouter::GetRegisteredEvents( |
318 const std::string& extension_id) const { | 344 const std::string& extension_id, |
| 345 RegisteredEventType type) const { |
319 std::set<std::string> events; | 346 std::set<std::string> events; |
320 const ListValue* events_value = NULL; | 347 const ListValue* events_value = NULL; |
321 | 348 |
322 if (!extension_prefs_ || | 349 const char* pref_key = type == RegisteredEventType::kLazy |
323 !extension_prefs_->ReadPrefAsList( | 350 ? kRegisteredLazyEvents |
324 extension_id, kRegisteredEvents, &events_value)) { | 351 : kRegisteredServiceWorkerEvents; |
| 352 if (!extension_prefs_ || !extension_prefs_->ReadPrefAsList( |
| 353 extension_id, pref_key, &events_value)) { |
325 return events; | 354 return events; |
326 } | 355 } |
327 | 356 |
328 for (size_t i = 0; i < events_value->GetSize(); ++i) { | 357 for (size_t i = 0; i < events_value->GetSize(); ++i) { |
329 std::string event; | 358 std::string event; |
330 if (events_value->GetString(i, &event)) | 359 if (events_value->GetString(i, &event)) |
331 events.insert(event); | 360 events.insert(event); |
332 } | 361 } |
333 return events; | 362 return events; |
334 } | 363 } |
335 | 364 |
| 365 void EventRouter::ClearRegisteredEventsForTest( |
| 366 const ExtensionId& extension_id) { |
| 367 SetRegisteredEvents(extension_id, std::set<std::string>(), |
| 368 RegisteredEventType::kLazy); |
| 369 SetRegisteredEvents(extension_id, std::set<std::string>(), |
| 370 RegisteredEventType::kServiceWorker); |
| 371 } |
| 372 |
336 void EventRouter::RemoveFilterFromEvent(const std::string& event_name, | 373 void EventRouter::RemoveFilterFromEvent(const std::string& event_name, |
337 const std::string& extension_id, | 374 const std::string& extension_id, |
338 const DictionaryValue* filter) { | 375 const DictionaryValue* filter) { |
339 ExtensionPrefs::ScopedDictionaryUpdate update( | 376 ExtensionPrefs::ScopedDictionaryUpdate update( |
340 extension_prefs_, extension_id, kFilteredEvents); | 377 extension_prefs_, extension_id, kFilteredEvents); |
341 auto filtered_events = update.Create(); | 378 auto filtered_events = update.Create(); |
342 ListValue* filter_list = NULL; | 379 ListValue* filter_list = NULL; |
343 if (!filtered_events || | 380 if (!filtered_events || |
344 !filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { | 381 !filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { |
345 return; | 382 return; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 if (!has_listener) | 421 if (!has_listener) |
385 RemoveLazyEventListener(event_name, extension_id); | 422 RemoveLazyEventListener(event_name, extension_id); |
386 } | 423 } |
387 | 424 |
388 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, | 425 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, |
389 const linked_ptr<Event>& event) { | 426 const linked_ptr<Event>& event) { |
390 // We don't expect to get events from a completely different browser context. | 427 // We don't expect to get events from a completely different browser context. |
391 DCHECK(!event->restrict_to_browser_context || | 428 DCHECK(!event->restrict_to_browser_context || |
392 ExtensionsBrowserClient::Get()->IsSameContext( | 429 ExtensionsBrowserClient::Get()->IsSameContext( |
393 browser_context_, event->restrict_to_browser_context)); | 430 browser_context_, event->restrict_to_browser_context)); |
394 | |
395 std::set<const EventListener*> listeners( | 431 std::set<const EventListener*> listeners( |
396 listeners_.GetEventListeners(*event)); | 432 listeners_.GetEventListeners(*event)); |
397 | 433 |
398 std::set<EventDispatchIdentifier> already_dispatched; | 434 std::set<EventDispatchIdentifier> already_dispatched; |
399 | 435 |
400 // We dispatch events for lazy background pages first because attempting to do | 436 // We dispatch events for lazy background pages first because attempting to do |
401 // so will cause those that are being suspended to cancel that suspension. | 437 // so will cause those that are being suspended to cancel that suspension. |
402 // As canceling a suspension entails sending an event to the affected | 438 // As canceling a suspension entails sending an event to the affected |
403 // background page, and as that event needs to be delivered before we dispatch | 439 // background page, and as that event needs to be delivered before we dispatch |
404 // the event we are dispatching here, we dispatch to the lazy listeners here | 440 // the event we are dispatching here, we dispatch to the lazy listeners here |
405 // first. | 441 // first. |
406 for (const EventListener* listener : listeners) { | 442 for (const EventListener* listener : listeners) { |
407 if (restrict_to_extension_id.empty() || | 443 if (restrict_to_extension_id.empty() || |
408 restrict_to_extension_id == listener->extension_id()) { | 444 restrict_to_extension_id == listener->extension_id()) { |
409 if (listener->IsLazy()) { | 445 // TODO(lazyboy): Support lazy listeners for extension SW events. |
| 446 if (listener->IsLazy() && !listener->IsForServiceWorker()) { |
410 DispatchLazyEvent(listener->extension_id(), event, &already_dispatched, | 447 DispatchLazyEvent(listener->extension_id(), event, &already_dispatched, |
411 listener->filter()); | 448 listener->filter()); |
412 } | 449 } |
413 } | 450 } |
414 } | 451 } |
415 | 452 |
416 for (const EventListener* listener : listeners) { | 453 for (const EventListener* listener : listeners) { |
417 if (restrict_to_extension_id.empty() || | 454 if (restrict_to_extension_id.empty() || |
418 restrict_to_extension_id == listener->extension_id()) { | 455 restrict_to_extension_id == listener->extension_id()) { |
419 if (listener->process()) { | 456 if (listener->process()) { |
420 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), | 457 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), |
421 listener->extension_id()); | 458 listener->extension_id(), |
| 459 listener->worker_thread_id()); |
422 if (!base::ContainsKey(already_dispatched, dispatch_id)) { | 460 if (!base::ContainsKey(already_dispatched, dispatch_id)) { |
423 DispatchEventToProcess(listener->extension_id(), | 461 DispatchEventToProcess(listener->extension_id(), |
424 listener->listener_url(), listener->process(), | 462 listener->listener_url(), listener->process(), |
425 event, listener->filter(), | 463 listener->worker_thread_id(), event, |
426 false /* did_enqueue */); | 464 listener->filter(), false /* did_enqueue */); |
427 } | 465 } |
428 } | 466 } |
429 } | 467 } |
430 } | 468 } |
431 } | 469 } |
432 | 470 |
433 void EventRouter::DispatchLazyEvent( | 471 void EventRouter::DispatchLazyEvent( |
434 const std::string& extension_id, | 472 const std::string& extension_id, |
435 const linked_ptr<Event>& event, | 473 const linked_ptr<Event>& event, |
436 std::set<EventDispatchIdentifier>* already_dispatched, | 474 std::set<EventDispatchIdentifier>* already_dispatched, |
437 const base::DictionaryValue* listener_filter) { | 475 const base::DictionaryValue* listener_filter) { |
438 // Check both the original and the incognito browser context to see if we | 476 // Check both the original and the incognito browser context to see if we |
439 // should load a lazy bg page to handle the event. The latter case | 477 // should load a lazy bg page to handle the event. The latter case |
440 // occurs in the case of split-mode extensions. | 478 // occurs in the case of split-mode extensions. |
441 const Extension* extension = | 479 const Extension* extension = |
442 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( | 480 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( |
443 extension_id); | 481 extension_id); |
444 if (!extension) | 482 if (!extension) |
445 return; | 483 return; |
446 | 484 |
447 if (MaybeLoadLazyBackgroundPageToDispatchEvent(browser_context_, extension, | 485 if (MaybeLoadLazyBackgroundPageToDispatchEvent(browser_context_, extension, |
448 event, listener_filter)) { | 486 event, listener_filter)) { |
449 already_dispatched->insert(std::make_pair(browser_context_, extension_id)); | 487 already_dispatched->insert( |
| 488 std::make_tuple(browser_context_, extension_id, kNonWorkerThreadId)); |
450 } | 489 } |
451 | 490 |
452 ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get(); | 491 ExtensionsBrowserClient* browser_client = ExtensionsBrowserClient::Get(); |
453 if (browser_client->HasOffTheRecordContext(browser_context_) && | 492 if (browser_client->HasOffTheRecordContext(browser_context_) && |
454 IncognitoInfo::IsSplitMode(extension)) { | 493 IncognitoInfo::IsSplitMode(extension)) { |
455 BrowserContext* incognito_context = | 494 BrowserContext* incognito_context = |
456 browser_client->GetOffTheRecordContext(browser_context_); | 495 browser_client->GetOffTheRecordContext(browser_context_); |
457 if (MaybeLoadLazyBackgroundPageToDispatchEvent(incognito_context, extension, | 496 if (MaybeLoadLazyBackgroundPageToDispatchEvent(incognito_context, extension, |
458 event, listener_filter)) { | 497 event, listener_filter)) { |
459 already_dispatched->insert( | 498 already_dispatched->insert( |
460 std::make_pair(incognito_context, extension_id)); | 499 std::make_tuple(incognito_context, extension_id, kNonWorkerThreadId)); |
461 } | 500 } |
462 } | 501 } |
463 } | 502 } |
464 | 503 |
465 void EventRouter::DispatchEventToProcess( | 504 void EventRouter::DispatchEventToProcess( |
466 const std::string& extension_id, | 505 const std::string& extension_id, |
467 const GURL& listener_url, | 506 const GURL& listener_url, |
468 content::RenderProcessHost* process, | 507 content::RenderProcessHost* process, |
| 508 int worker_thread_id, |
469 const linked_ptr<Event>& event, | 509 const linked_ptr<Event>& event, |
470 const base::DictionaryValue* listener_filter, | 510 const base::DictionaryValue* listener_filter, |
471 bool did_enqueue) { | 511 bool did_enqueue) { |
472 BrowserContext* listener_context = process->GetBrowserContext(); | 512 BrowserContext* listener_context = process->GetBrowserContext(); |
473 ProcessMap* process_map = ProcessMap::Get(listener_context); | 513 ProcessMap* process_map = ProcessMap::Get(listener_context); |
474 | 514 |
475 // NOTE: |extension| being NULL does not necessarily imply that this event | 515 // NOTE: |extension| being NULL does not necessarily imply that this event |
476 // shouldn't be dispatched. Events can be dispatched to WebUI and webviews as | 516 // shouldn't be dispatched. Events can be dispatched to WebUI and webviews as |
477 // well. It all depends on what GetMostLikelyContextType returns. | 517 // well. It all depends on what GetMostLikelyContextType returns. |
478 const Extension* extension = | 518 const Extension* extension = |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 return; | 566 return; |
527 } | 567 } |
528 | 568 |
529 if (!event->will_dispatch_callback.is_null() && | 569 if (!event->will_dispatch_callback.is_null() && |
530 !event->will_dispatch_callback.Run(listener_context, extension, | 570 !event->will_dispatch_callback.Run(listener_context, extension, |
531 event.get(), listener_filter)) { | 571 event.get(), listener_filter)) { |
532 return; | 572 return; |
533 } | 573 } |
534 | 574 |
535 int event_id = g_extension_event_id.GetNext(); | 575 int event_id = g_extension_event_id.GetNext(); |
536 DispatchExtensionMessage(process, listener_context, extension_id, event_id, | 576 DispatchExtensionMessage(process, worker_thread_id, listener_context, |
537 event->event_name, event->event_args.get(), | 577 extension_id, event_id, event->event_name, |
538 event->user_gesture, event->filter_info); | 578 event->event_args.get(), event->user_gesture, |
| 579 event->filter_info); |
539 | 580 |
540 if (extension) { | 581 if (extension) { |
541 ReportEvent(event->histogram_value, extension, did_enqueue); | 582 ReportEvent(event->histogram_value, extension, did_enqueue); |
542 IncrementInFlightEvents(listener_context, extension, event_id, | 583 IncrementInFlightEvents(listener_context, extension, event_id, |
543 event->event_name); | 584 event->event_name); |
544 } | 585 } |
545 } | 586 } |
546 | 587 |
547 bool EventRouter::CanDispatchEventToBrowserContext( | 588 bool EventRouter::CanDispatchEventToBrowserContext( |
548 BrowserContext* context, | 589 BrowserContext* context, |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 } | 740 } |
700 } | 741 } |
701 } | 742 } |
702 | 743 |
703 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, | 744 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, |
704 ExtensionHost* host) { | 745 ExtensionHost* host) { |
705 if (!host) | 746 if (!host) |
706 return; | 747 return; |
707 | 748 |
708 if (listeners_.HasProcessListener(host->render_process_host(), | 749 if (listeners_.HasProcessListener(host->render_process_host(), |
| 750 kNonWorkerThreadId, |
709 host->extension()->id())) { | 751 host->extension()->id())) { |
710 DispatchEventToProcess(host->extension()->id(), host->GetURL(), | 752 DispatchEventToProcess(host->extension()->id(), host->GetURL(), |
711 host->render_process_host(), event, nullptr, | 753 host->render_process_host(), kNonWorkerThreadId, |
712 true /* did_enqueue */); | 754 event, nullptr, true /* did_enqueue */); |
713 } | 755 } |
714 } | 756 } |
715 | 757 |
716 void EventRouter::SetRegisteredEvents(const std::string& extension_id, | 758 void EventRouter::SetRegisteredEvents(const std::string& extension_id, |
717 const std::set<std::string>& events) { | 759 const std::set<std::string>& events, |
| 760 RegisteredEventType type) { |
718 auto events_value = base::MakeUnique<base::ListValue>(); | 761 auto events_value = base::MakeUnique<base::ListValue>(); |
719 for (std::set<std::string>::const_iterator iter = events.begin(); | 762 for (std::set<std::string>::const_iterator iter = events.begin(); |
720 iter != events.end(); ++iter) { | 763 iter != events.end(); ++iter) { |
721 events_value->AppendString(*iter); | 764 events_value->AppendString(*iter); |
722 } | 765 } |
723 extension_prefs_->UpdateExtensionPref(extension_id, kRegisteredEvents, | 766 const char* pref_key = type == RegisteredEventType::kLazy |
| 767 ? kRegisteredLazyEvents |
| 768 : kRegisteredServiceWorkerEvents; |
| 769 extension_prefs_->UpdateExtensionPref(extension_id, pref_key, |
724 std::move(events_value)); | 770 std::move(events_value)); |
725 } | 771 } |
726 | 772 |
727 void EventRouter::AddFilterToEvent(const std::string& event_name, | 773 void EventRouter::AddFilterToEvent(const std::string& event_name, |
728 const std::string& extension_id, | 774 const std::string& extension_id, |
729 const DictionaryValue* filter) { | 775 const DictionaryValue* filter) { |
730 ExtensionPrefs::ScopedDictionaryUpdate update(extension_prefs_, extension_id, | 776 ExtensionPrefs::ScopedDictionaryUpdate update(extension_prefs_, extension_id, |
731 kFilteredEvents); | 777 kFilteredEvents); |
732 auto filtered_events = update.Create(); | 778 auto filtered_events = update.Create(); |
733 | 779 |
734 ListValue* filter_list = nullptr; | 780 ListValue* filter_list = nullptr; |
735 if (!filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { | 781 if (!filtered_events->GetListWithoutPathExpansion(event_name, &filter_list)) { |
736 filtered_events->SetWithoutPathExpansion( | 782 filtered_events->SetWithoutPathExpansion( |
737 event_name, base::MakeUnique<base::ListValue>()); | 783 event_name, base::MakeUnique<base::ListValue>()); |
738 filtered_events->GetListWithoutPathExpansion(event_name, &filter_list); | 784 filtered_events->GetListWithoutPathExpansion(event_name, &filter_list); |
739 } | 785 } |
740 | 786 |
741 filter_list->Append(filter->CreateDeepCopy()); | 787 filter_list->Append(filter->CreateDeepCopy()); |
742 } | 788 } |
743 | 789 |
744 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, | 790 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, |
745 const Extension* extension) { | 791 const Extension* extension) { |
746 // Add all registered lazy listeners to our cache. | 792 // Add all registered lazy listeners to our cache. |
| 793 // TODO(lazyboy): Load extension SW lazy events. |
747 std::set<std::string> registered_events = | 794 std::set<std::string> registered_events = |
748 GetRegisteredEvents(extension->id()); | 795 GetRegisteredEvents(extension->id(), RegisteredEventType::kLazy); |
749 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); | 796 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); |
| 797 // TODO(lazyboy): Load extension SW filtered events when they are available. |
750 const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); | 798 const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); |
751 if (filtered_events) | 799 if (filtered_events) |
752 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); | 800 listeners_.LoadFilteredLazyListeners(extension->id(), *filtered_events); |
753 } | 801 } |
754 | 802 |
755 void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context, | 803 void EventRouter::OnExtensionUnloaded(content::BrowserContext* browser_context, |
756 const Extension* extension, | 804 const Extension* extension, |
757 UnloadedExtensionReason reason) { | 805 UnloadedExtensionReason reason) { |
758 // Remove all registered listeners from our cache. | 806 // Remove all registered listeners from our cache. |
759 listeners_.RemoveListenersForExtension(extension->id()); | 807 listeners_.RemoveListenersForExtension(extension->id()); |
760 } | 808 } |
761 | 809 |
| 810 void EventRouter::AddLazyEventListenerImpl(const std::string& event_name, |
| 811 const ExtensionId& extension_id, |
| 812 int worker_thread_id) { |
| 813 bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId; |
| 814 bool is_new = listeners_.AddListener( |
| 815 is_for_service_worker |
| 816 ? EventListener::ForExtensionServiceWorker( |
| 817 event_name, extension_id, nullptr, worker_thread_id, nullptr) |
| 818 : EventListener::ForExtension(event_name, extension_id, nullptr, |
| 819 nullptr)); |
| 820 |
| 821 if (is_new) { |
| 822 RegisteredEventType type = is_for_service_worker |
| 823 ? RegisteredEventType::kServiceWorker |
| 824 : RegisteredEventType::kLazy; |
| 825 std::set<std::string> events = GetRegisteredEvents(extension_id, type); |
| 826 bool prefs_is_new = events.insert(event_name).second; |
| 827 if (prefs_is_new) |
| 828 SetRegisteredEvents(extension_id, events, type); |
| 829 } |
| 830 } |
| 831 |
| 832 void EventRouter::RemoveLazyEventListenerImpl(const std::string& event_name, |
| 833 const ExtensionId& extension_id, |
| 834 int worker_thread_id) { |
| 835 bool is_for_service_worker = worker_thread_id != kNonWorkerThreadId; |
| 836 std::unique_ptr<EventListener> listener = |
| 837 is_for_service_worker |
| 838 ? EventListener::ForExtensionServiceWorker( |
| 839 event_name, extension_id, nullptr, worker_thread_id, nullptr) |
| 840 : EventListener::ForExtension(event_name, extension_id, nullptr, |
| 841 nullptr); |
| 842 bool did_exist = listeners_.RemoveListener(listener.get()); |
| 843 |
| 844 if (did_exist) { |
| 845 RegisteredEventType type = is_for_service_worker |
| 846 ? RegisteredEventType::kServiceWorker |
| 847 : RegisteredEventType::kLazy; |
| 848 std::set<std::string> events = GetRegisteredEvents(extension_id, type); |
| 849 bool prefs_did_exist = events.erase(event_name) > 0; |
| 850 DCHECK(prefs_did_exist); |
| 851 SetRegisteredEvents(extension_id, events, type); |
| 852 } |
| 853 } |
| 854 |
762 Event::Event(events::HistogramValue histogram_value, | 855 Event::Event(events::HistogramValue histogram_value, |
763 const std::string& event_name, | 856 const std::string& event_name, |
764 std::unique_ptr<base::ListValue> event_args) | 857 std::unique_ptr<base::ListValue> event_args) |
765 : Event(histogram_value, event_name, std::move(event_args), nullptr) {} | 858 : Event(histogram_value, event_name, std::move(event_args), nullptr) {} |
766 | 859 |
767 Event::Event(events::HistogramValue histogram_value, | 860 Event::Event(events::HistogramValue histogram_value, |
768 const std::string& event_name, | 861 const std::string& event_name, |
769 std::unique_ptr<base::ListValue> event_args, | 862 std::unique_ptr<base::ListValue> event_args, |
770 BrowserContext* restrict_to_browser_context) | 863 BrowserContext* restrict_to_browser_context) |
771 : Event(histogram_value, | 864 : Event(histogram_value, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 const std::string& extension_id, | 907 const std::string& extension_id, |
815 const GURL& listener_url, | 908 const GURL& listener_url, |
816 content::BrowserContext* browser_context) | 909 content::BrowserContext* browser_context) |
817 : event_name(event_name), | 910 : event_name(event_name), |
818 extension_id(extension_id), | 911 extension_id(extension_id), |
819 listener_url(listener_url), | 912 listener_url(listener_url), |
820 browser_context(browser_context) { | 913 browser_context(browser_context) { |
821 } | 914 } |
822 | 915 |
823 } // namespace extensions | 916 } // namespace extensions |
OLD | NEW |