Chromium Code Reviews| 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 |