Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: extensions/renderer/event_bindings.cc

Issue 2973903002: [Extensions Bindings] Introduce a supportsLazyListeners property (Closed)
Patch Set: onMessage event fix Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 context->v8_context()), 231 context->v8_context()),
232 listener_ids, 232 listener_ids,
233 }; 233 };
234 234
235 context->module_system()->CallModuleMethodSafe( 235 context->module_system()->CallModuleMethodSafe(
236 kEventBindings, "dispatchEvent", arraysize(v8_args), v8_args); 236 kEventBindings, "dispatchEvent", arraysize(v8_args), v8_args);
237 } 237 }
238 238
239 void EventBindings::AttachEventHandler( 239 void EventBindings::AttachEventHandler(
240 const v8::FunctionCallbackInfo<v8::Value>& args) { 240 const v8::FunctionCallbackInfo<v8::Value>& args) {
241 CHECK_EQ(1, args.Length()); 241 CHECK_EQ(2, args.Length());
242 CHECK(args[0]->IsString()); 242 CHECK(args[0]->IsString());
243 AttachEvent(*v8::String::Utf8Value(args[0])); 243 CHECK(args[1]->IsBoolean());
244 AttachEvent(*v8::String::Utf8Value(args[0]), args[1]->BooleanValue());
244 } 245 }
245 246
246 void EventBindings::AttachEvent(const std::string& event_name) { 247 void EventBindings::AttachEvent(const std::string& event_name,
248 bool supports_lazy_listeners) {
247 if (!context()->HasAccessOrThrowError(event_name)) 249 if (!context()->HasAccessOrThrowError(event_name))
248 return; 250 return;
249 251
250 // Record the attachment for this context so that events can be detached when 252 // Record the attachment for this context so that events can be detached when
251 // the context is destroyed. 253 // the context is destroyed.
252 // 254 //
253 // Ideally we'd CHECK that it's not already attached, however that's not 255 // Ideally we'd CHECK that it's not already attached, however that's not
254 // possible because extensions can create and attach events themselves. Very 256 // possible because extensions can create and attach events themselves. Very
255 // silly, but that's the way it is. For an example of this, see 257 // silly, but that's the way it is. For an example of this, see
256 // chrome/test/data/extensions/api_test/events/background.js. 258 // chrome/test/data/extensions/api_test/events/background.js.
257 attached_event_names_.insert(event_name); 259 attached_event_names_.insert(event_name);
258 260
259 if (IncrementEventListenerCount(context(), event_name) == 1) { 261 if (IncrementEventListenerCount(context(), event_name) == 1) {
260 ipc_message_sender_->SendAddUnfilteredEventListenerIPC(context(), 262 ipc_message_sender_->SendAddUnfilteredEventListenerIPC(context(),
261 event_name); 263 event_name);
262 } 264 }
263 265
264 // This is called the first time the page has added a listener. Since 266 // This is called the first time the page has added a listener. Since
265 // the background page is the only lazy page, we know this is the first 267 // the background page is the only lazy page, we know this is the first
266 // time this listener has been registered. 268 // time this listener has been registered.
267 if (IsLazyContext(context())) { 269 if (IsLazyContext(context()) && supports_lazy_listeners) {
268 ipc_message_sender_->SendAddUnfilteredLazyEventListenerIPC(context(), 270 ipc_message_sender_->SendAddUnfilteredLazyEventListenerIPC(context(),
269 event_name); 271 event_name);
270 } 272 }
271 } 273 }
272 274
273 void EventBindings::DetachEventHandler( 275 void EventBindings::DetachEventHandler(
274 const v8::FunctionCallbackInfo<v8::Value>& args) { 276 const v8::FunctionCallbackInfo<v8::Value>& args) {
275 CHECK_EQ(2, args.Length()); 277 CHECK_EQ(3, args.Length());
276 CHECK(args[0]->IsString()); 278 CHECK(args[0]->IsString());
277 CHECK(args[1]->IsBoolean()); 279 CHECK(args[1]->IsBoolean());
278 DetachEvent(*v8::String::Utf8Value(args[0]), args[1]->BooleanValue()); 280 CHECK(args[2]->IsBoolean());
281 bool was_manual = args[1]->BooleanValue();
282 bool supports_lazy_listeners = args[2]->BooleanValue();
283 DetachEvent(*v8::String::Utf8Value(args[0]),
284 was_manual && supports_lazy_listeners);
279 } 285 }
280 286
281 void EventBindings::DetachEvent(const std::string& event_name, bool is_manual) { 287 void EventBindings::DetachEvent(const std::string& event_name,
288 bool remove_lazy_listener) {
282 // See comment in AttachEvent(). 289 // See comment in AttachEvent().
283 attached_event_names_.erase(event_name); 290 attached_event_names_.erase(event_name);
284 291
285 if (DecrementEventListenerCount(context(), event_name) == 0) { 292 if (DecrementEventListenerCount(context(), event_name) == 0) {
286 ipc_message_sender_->SendRemoveUnfilteredEventListenerIPC(context(), 293 ipc_message_sender_->SendRemoveUnfilteredEventListenerIPC(context(),
287 event_name); 294 event_name);
288 } 295 }
289 296
290 // DetachEvent is called when the last listener for the context is 297 // DetachEvent is called when the last listener for the context is
291 // removed. If the context is the background page or service worker, and it 298 // removed. If the context is the background page or service worker, and it
292 // removes the last listener manually, then we assume that it is no longer 299 // removes the last listener manually, then we assume that it is no longer
293 // interested in being awakened for this event. 300 // interested in being awakened for this event.
294 if (is_manual && IsLazyContext(context())) { 301 if (remove_lazy_listener && IsLazyContext(context())) {
295 ipc_message_sender_->SendRemoveUnfilteredLazyEventListenerIPC(context(), 302 ipc_message_sender_->SendRemoveUnfilteredLazyEventListenerIPC(context(),
296 event_name); 303 event_name);
297 } 304 }
298 } 305 }
299 306
300 // MatcherID AttachFilteredEvent(string event_name, object filter) 307 // MatcherID AttachFilteredEvent(string event_name, object filter)
301 // event_name - Name of the event to attach. 308 // event_name - Name of the event to attach.
302 // filter - Which instances of the named event are we interested in. 309 // filter - Which instances of the named event are we interested in.
303 // returns the id assigned to the listener, which will be provided to calls to 310 // returns the id assigned to the listener, which will be provided to calls to
304 // dispatchEvent(). 311 // dispatchEvent().
305 void EventBindings::AttachFilteredEvent( 312 void EventBindings::AttachFilteredEvent(
306 const v8::FunctionCallbackInfo<v8::Value>& args) { 313 const v8::FunctionCallbackInfo<v8::Value>& args) {
307 CHECK_EQ(2, args.Length()); 314 CHECK_EQ(3, args.Length());
308 CHECK(args[0]->IsString()); 315 CHECK(args[0]->IsString());
309 CHECK(args[1]->IsObject()); 316 CHECK(args[1]->IsObject());
317 CHECK(args[2]->IsBoolean());
310 318
311 std::string event_name = *v8::String::Utf8Value(args[0]); 319 std::string event_name = *v8::String::Utf8Value(args[0]);
312 if (!context()->HasAccessOrThrowError(event_name)) 320 if (!context()->HasAccessOrThrowError(event_name))
313 return; 321 return;
314 322
315 std::unique_ptr<base::DictionaryValue> filter; 323 std::unique_ptr<base::DictionaryValue> filter;
316 { 324 {
317 std::unique_ptr<base::Value> filter_value = 325 std::unique_ptr<base::Value> filter_value =
318 content::V8ValueConverter::Create()->FromV8Value( 326 content::V8ValueConverter::Create()->FromV8Value(
319 v8::Local<v8::Object>::Cast(args[1]), context()->v8_context()); 327 v8::Local<v8::Object>::Cast(args[1]), context()->v8_context());
320 if (!filter_value || !filter_value->IsType(base::Value::Type::DICTIONARY)) { 328 if (!filter_value || !filter_value->IsType(base::Value::Type::DICTIONARY)) {
321 args.GetReturnValue().Set(static_cast<int32_t>(-1)); 329 args.GetReturnValue().Set(static_cast<int32_t>(-1));
322 return; 330 return;
323 } 331 }
324 filter = base::DictionaryValue::From(std::move(filter_value)); 332 filter = base::DictionaryValue::From(std::move(filter_value));
325 } 333 }
326 334
335 bool supports_lazy_listeners = args[2]->BooleanValue();
336
327 int id = g_event_filter.Get().AddEventMatcher( 337 int id = g_event_filter.Get().AddEventMatcher(
328 event_name, 338 event_name,
329 base::MakeUnique<EventMatcher>( 339 base::MakeUnique<EventMatcher>(
330 std::move(filter), context()->GetRenderFrame()->GetRoutingID())); 340 std::move(filter), context()->GetRenderFrame()->GetRoutingID()));
331 if (id == -1) { 341 if (id == -1) {
332 args.GetReturnValue().Set(static_cast<int32_t>(-1)); 342 args.GetReturnValue().Set(static_cast<int32_t>(-1));
333 return; 343 return;
334 } 344 }
335 attached_matcher_ids_.insert(id); 345 attached_matcher_ids_.insert(id);
336 346
337 // Only send IPCs the first time a filter gets added. 347 // Only send IPCs the first time a filter gets added.
338 const EventMatcher* matcher = g_event_filter.Get().GetEventMatcher(id); 348 const EventMatcher* matcher = g_event_filter.Get().GetEventMatcher(id);
339 DCHECK(matcher); 349 DCHECK(matcher);
340 base::DictionaryValue* filter_weak = matcher->value(); 350 base::DictionaryValue* filter_weak = matcher->value();
341 const ExtensionId& extension_id = context()->GetExtensionID(); 351 const ExtensionId& extension_id = context()->GetExtensionID();
342 if (AddFilter(event_name, extension_id, *filter_weak)) { 352 if (AddFilter(event_name, extension_id, *filter_weak)) {
343 bool lazy = ExtensionFrameHelper::IsContextForEventPage(context()); 353 bool lazy = supports_lazy_listeners &&
354 ExtensionFrameHelper::IsContextForEventPage(context());
344 ipc_message_sender_->SendAddFilteredEventListenerIPC(context(), event_name, 355 ipc_message_sender_->SendAddFilteredEventListenerIPC(context(), event_name,
345 *filter_weak, lazy); 356 *filter_weak, lazy);
346 } 357 }
347 358
348 args.GetReturnValue().Set(static_cast<int32_t>(id)); 359 args.GetReturnValue().Set(static_cast<int32_t>(id));
349 } 360 }
350 361
351 void EventBindings::DetachFilteredEventHandler( 362 void EventBindings::DetachFilteredEventHandler(
352 const v8::FunctionCallbackInfo<v8::Value>& args) { 363 const v8::FunctionCallbackInfo<v8::Value>& args) {
353 CHECK_EQ(2, args.Length()); 364 CHECK_EQ(3, args.Length());
354 CHECK(args[0]->IsInt32()); 365 CHECK(args[0]->IsInt32());
355 CHECK(args[1]->IsBoolean()); 366 CHECK(args[1]->IsBoolean());
356 DetachFilteredEvent(args[0]->Int32Value(), args[1]->BooleanValue()); 367 CHECK(args[2]->IsBoolean());
368 bool was_manual = args[1]->BooleanValue();
369 bool supports_lazy_listeners = args[2]->BooleanValue();
370 DetachFilteredEvent(args[0]->Int32Value(),
371 was_manual && supports_lazy_listeners);
357 } 372 }
358 373
359 void EventBindings::DetachFilteredEvent(int matcher_id, bool is_manual) { 374 void EventBindings::DetachFilteredEvent(int matcher_id,
375 bool remove_lazy_event) {
360 EventFilter& event_filter = g_event_filter.Get(); 376 EventFilter& event_filter = g_event_filter.Get();
361 EventMatcher* event_matcher = event_filter.GetEventMatcher(matcher_id); 377 EventMatcher* event_matcher = event_filter.GetEventMatcher(matcher_id);
362 378
363 const std::string& event_name = event_filter.GetEventName(matcher_id); 379 const std::string& event_name = event_filter.GetEventName(matcher_id);
364 380
365 // Only send IPCs the last time a filter gets removed. 381 // Only send IPCs the last time a filter gets removed.
366 const ExtensionId& extension_id = context()->GetExtensionID(); 382 const ExtensionId& extension_id = context()->GetExtensionID();
367 if (RemoveFilter(event_name, extension_id, event_matcher->value())) { 383 if (RemoveFilter(event_name, extension_id, event_matcher->value())) {
368 bool remove_lazy = 384 bool remove_lazy = remove_lazy_event &&
369 is_manual && ExtensionFrameHelper::IsContextForEventPage(context()); 385 ExtensionFrameHelper::IsContextForEventPage(context());
370 ipc_message_sender_->SendRemoveFilteredEventListenerIPC( 386 ipc_message_sender_->SendRemoveFilteredEventListenerIPC(
371 context(), event_name, *event_matcher->value(), remove_lazy); 387 context(), event_name, *event_matcher->value(), remove_lazy);
372 } 388 }
373 389
374 event_filter.RemoveEventMatcher(matcher_id); 390 event_filter.RemoveEventMatcher(matcher_id);
375 attached_matcher_ids_.erase(matcher_id); 391 attached_matcher_ids_.erase(matcher_id);
376 } 392 }
377 393
378 void EventBindings::AttachUnmanagedEvent( 394 void EventBindings::AttachUnmanagedEvent(
379 const v8::FunctionCallbackInfo<v8::Value>& args) { 395 const v8::FunctionCallbackInfo<v8::Value>& args) {
(...skipping 30 matching lines...) Expand all
410 for (int matcher_id : attached_matcher_ids_safe) { 426 for (int matcher_id : attached_matcher_ids_safe) {
411 DetachFilteredEvent(matcher_id, false /* is_manual */); 427 DetachFilteredEvent(matcher_id, false /* is_manual */);
412 } 428 }
413 DCHECK(attached_matcher_ids_.empty()) 429 DCHECK(attached_matcher_ids_.empty())
414 << "Filtered events cannot be attached during invalidation"; 430 << "Filtered events cannot be attached during invalidation";
415 431
416 g_unmanaged_listeners.Get().erase(context()); 432 g_unmanaged_listeners.Get().erase(context());
417 } 433 }
418 434
419 } // namespace extensions 435 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/event_bindings.h ('k') | extensions/renderer/native_extension_bindings_system.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698