OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/renderer/event_bindings.h" | 5 #include "extensions/renderer/event_bindings.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <memory> | 10 #include <memory> |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 // the context is destroyed. | 242 // the context is destroyed. |
243 // | 243 // |
244 // Ideally we'd CHECK that it's not already attached, however that's not | 244 // Ideally we'd CHECK that it's not already attached, however that's not |
245 // possible because extensions can create and attach events themselves. Very | 245 // possible because extensions can create and attach events themselves. Very |
246 // silly, but that's the way it is. For an example of this, see | 246 // silly, but that's the way it is. For an example of this, see |
247 // chrome/test/data/extensions/api_test/events/background.js. | 247 // chrome/test/data/extensions/api_test/events/background.js. |
248 attached_event_names_.insert(event_name); | 248 attached_event_names_.insert(event_name); |
249 | 249 |
250 const int worker_thread_id = content::WorkerThread::GetCurrentId(); | 250 const int worker_thread_id = content::WorkerThread::GetCurrentId(); |
251 const std::string& extension_id = context()->GetExtensionID(); | 251 const std::string& extension_id = context()->GetExtensionID(); |
| 252 const bool is_service_worker_context = |
| 253 context()->context_type() == Feature::SERVICE_WORKER_CONTEXT; |
252 IPC::Sender* sender = GetIPCSender(); | 254 IPC::Sender* sender = GetIPCSender(); |
253 if (IncrementEventListenerCount(context(), event_name) == 1) { | 255 if (IncrementEventListenerCount(context(), event_name) == 1) { |
254 sender->Send(new ExtensionHostMsg_AddListener( | 256 sender->Send(new ExtensionHostMsg_AddListener( |
255 extension_id, context()->url(), event_name, worker_thread_id)); | 257 extension_id, |
| 258 is_service_worker_context ? context()->service_worker_scope() |
| 259 : context()->url(), |
| 260 event_name, worker_thread_id)); |
256 } | 261 } |
257 | 262 |
258 // This is called the first time the page has added a listener. Since | 263 // This is called the first time the page has added a listener. Since |
259 // the background page is the only lazy page, we know this is the first | 264 // the background page is the only lazy page, we know this is the first |
260 // time this listener has been registered. | 265 // time this listener has been registered. |
261 bool is_lazy_context = | 266 bool is_lazy_context = |
262 ExtensionFrameHelper::IsContextForEventPage(context()) || | 267 ExtensionFrameHelper::IsContextForEventPage(context()) || |
263 context()->context_type() == Feature::SERVICE_WORKER_CONTEXT; | 268 context()->context_type() == Feature::SERVICE_WORKER_CONTEXT; |
264 if (is_lazy_context) { | 269 if (is_lazy_context) { |
265 sender->Send(new ExtensionHostMsg_AddLazyListener(extension_id, event_name, | 270 if (is_service_worker_context) { |
266 worker_thread_id)); | 271 sender->Send(new ExtensionHostMsg_AddLazyServiceWorkerListener( |
| 272 extension_id, event_name, context()->service_worker_scope())); |
| 273 } else { |
| 274 sender->Send( |
| 275 new ExtensionHostMsg_AddLazyListener(extension_id, event_name)); |
| 276 } |
267 } | 277 } |
268 } | 278 } |
269 | 279 |
270 void EventBindings::DetachEventHandler( | 280 void EventBindings::DetachEventHandler( |
271 const v8::FunctionCallbackInfo<v8::Value>& args) { | 281 const v8::FunctionCallbackInfo<v8::Value>& args) { |
272 CHECK_EQ(2, args.Length()); | 282 CHECK_EQ(2, args.Length()); |
273 CHECK(args[0]->IsString()); | 283 CHECK(args[0]->IsString()); |
274 CHECK(args[1]->IsBoolean()); | 284 CHECK(args[1]->IsBoolean()); |
275 DetachEvent(*v8::String::Utf8Value(args[0]), args[1]->BooleanValue()); | 285 DetachEvent(*v8::String::Utf8Value(args[0]), args[1]->BooleanValue()); |
276 } | 286 } |
277 | 287 |
278 void EventBindings::DetachEvent(const std::string& event_name, bool is_manual) { | 288 void EventBindings::DetachEvent(const std::string& event_name, bool is_manual) { |
279 // See comment in AttachEvent(). | 289 // See comment in AttachEvent(). |
280 attached_event_names_.erase(event_name); | 290 attached_event_names_.erase(event_name); |
281 | 291 |
282 int worker_thread_id = content::WorkerThread::GetCurrentId(); | 292 int worker_thread_id = content::WorkerThread::GetCurrentId(); |
| 293 const bool is_service_worker_context = worker_thread_id != kNonWorkerThreadId; |
283 IPC::Sender* sender = GetIPCSender(); | 294 IPC::Sender* sender = GetIPCSender(); |
284 const std::string& extension_id = context()->GetExtensionID(); | 295 const std::string& extension_id = context()->GetExtensionID(); |
285 | 296 |
286 if (DecrementEventListenerCount(context(), event_name) == 0) { | 297 if (DecrementEventListenerCount(context(), event_name) == 0) { |
287 sender->Send(new ExtensionHostMsg_RemoveListener( | 298 sender->Send(new ExtensionHostMsg_RemoveListener( |
288 extension_id, context()->url(), event_name, worker_thread_id)); | 299 extension_id, |
| 300 is_service_worker_context ? context()->service_worker_scope() |
| 301 : context()->url(), |
| 302 event_name, worker_thread_id)); |
289 } | 303 } |
290 | 304 |
291 // DetachEvent is called when the last listener for the context is | 305 // DetachEvent is called when the last listener for the context is |
292 // removed. If the context is the background page or service worker, and it | 306 // removed. If the context is the background page or service worker, and it |
293 // removes the last listener manually, then we assume that it is no longer | 307 // removes the last listener manually, then we assume that it is no longer |
294 // interested in being awakened for this event. | 308 // interested in being awakened for this event. |
295 if (is_manual) { | 309 if (is_manual) { |
296 bool is_lazy_context = | 310 bool is_lazy_context = |
297 ExtensionFrameHelper::IsContextForEventPage(context()) || | 311 ExtensionFrameHelper::IsContextForEventPage(context()) || |
298 context()->context_type() == Feature::SERVICE_WORKER_CONTEXT; | 312 context()->context_type() == Feature::SERVICE_WORKER_CONTEXT; |
299 if (is_lazy_context) { | 313 if (is_lazy_context) { |
300 sender->Send(new ExtensionHostMsg_RemoveLazyListener( | 314 if (is_service_worker_context) { |
301 extension_id, event_name, worker_thread_id)); | 315 sender->Send(new ExtensionHostMsg_RemoveLazyServiceWorkerListener( |
| 316 extension_id, event_name, context()->service_worker_scope())); |
| 317 } else { |
| 318 sender->Send( |
| 319 new ExtensionHostMsg_RemoveLazyListener(extension_id, event_name)); |
| 320 } |
302 } | 321 } |
303 } | 322 } |
304 } | 323 } |
305 | 324 |
306 // MatcherID AttachFilteredEvent(string event_name, object filter) | 325 // MatcherID AttachFilteredEvent(string event_name, object filter) |
307 // event_name - Name of the event to attach. | 326 // event_name - Name of the event to attach. |
308 // filter - Which instances of the named event are we interested in. | 327 // filter - Which instances of the named event are we interested in. |
309 // returns the id assigned to the listener, which will be provided to calls to | 328 // returns the id assigned to the listener, which will be provided to calls to |
310 // dispatchEvent(). | 329 // dispatchEvent(). |
311 void EventBindings::AttachFilteredEvent( | 330 void EventBindings::AttachFilteredEvent( |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 for (int matcher_id : attached_matcher_ids_safe) { | 446 for (int matcher_id : attached_matcher_ids_safe) { |
428 DetachFilteredEvent(matcher_id, false /* is_manual */); | 447 DetachFilteredEvent(matcher_id, false /* is_manual */); |
429 } | 448 } |
430 DCHECK(attached_matcher_ids_.empty()) | 449 DCHECK(attached_matcher_ids_.empty()) |
431 << "Filtered events cannot be attached during invalidation"; | 450 << "Filtered events cannot be attached during invalidation"; |
432 | 451 |
433 g_unmanaged_listeners.Get().erase(context()); | 452 g_unmanaged_listeners.Get().erase(context()); |
434 } | 453 } |
435 | 454 |
436 } // namespace extensions | 455 } // namespace extensions |
OLD | NEW |