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