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 "chrome/renderer/extensions/dispatcher.h" | 5 #include "chrome/renderer/extensions/dispatcher.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/debug/alias.h" | 9 #include "base/debug/alias.h" |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 using WebKit::WebView; | 92 using WebKit::WebView; |
93 using content::RenderThread; | 93 using content::RenderThread; |
94 using content::RenderView; | 94 using content::RenderView; |
95 | 95 |
96 namespace extensions { | 96 namespace extensions { |
97 | 97 |
98 namespace { | 98 namespace { |
99 | 99 |
100 static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000; | 100 static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000; |
101 static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000; | 101 static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000; |
102 static const char kEventDispatchFunction[] = "Event.dispatchEvent"; | 102 static const char kEventModule[] = "event_bindings"; |
| 103 static const char kEventDispatchFunction[] = "dispatchEvent"; |
103 static const char kOnSuspendEvent[] = "runtime.onSuspend"; | 104 static const char kOnSuspendEvent[] = "runtime.onSuspend"; |
104 static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled"; | 105 static const char kOnSuspendCanceledEvent[] = "runtime.onSuspendCanceled"; |
105 | 106 |
106 static v8::Handle<v8::Object> GetOrCreateChrome( | 107 static v8::Handle<v8::Object> GetOrCreateChrome( |
107 v8::Handle<v8::Context> context) { | 108 v8::Handle<v8::Context> context) { |
108 v8::Handle<v8::String> chrome_string(v8::String::New("chrome")); | 109 v8::Handle<v8::String> chrome_string(v8::String::New("chrome")); |
109 v8::Handle<v8::Object> global(context->Global()); | 110 v8::Handle<v8::Object> global(context->Global()); |
110 v8::Handle<v8::Value> chrome(global->Get(chrome_string)); | 111 v8::Handle<v8::Value> chrome(global->Get(chrome_string)); |
111 if (chrome.IsEmpty() || chrome->IsUndefined()) { | 112 if (chrome.IsEmpty() || chrome->IsUndefined()) { |
112 v8::Handle<v8::Object> chrome_object(v8::Object::New()); | 113 v8::Handle<v8::Object> chrome_object(v8::Object::New()); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 }; | 361 }; |
361 | 362 |
362 class LoggingNativeHandler : public ObjectBackedNativeHandler { | 363 class LoggingNativeHandler : public ObjectBackedNativeHandler { |
363 public: | 364 public: |
364 explicit LoggingNativeHandler(ChromeV8Context* context) | 365 explicit LoggingNativeHandler(ChromeV8Context* context) |
365 : ObjectBackedNativeHandler(context) { | 366 : ObjectBackedNativeHandler(context) { |
366 RouteFunction("DCHECK", | 367 RouteFunction("DCHECK", |
367 base::Bind(&LoggingNativeHandler::Dcheck, base::Unretained(this))); | 368 base::Bind(&LoggingNativeHandler::Dcheck, base::Unretained(this))); |
368 RouteFunction("CHECK", | 369 RouteFunction("CHECK", |
369 base::Bind(&LoggingNativeHandler::Check, base::Unretained(this))); | 370 base::Bind(&LoggingNativeHandler::Check, base::Unretained(this))); |
| 371 RouteFunction("DCHECK_IS_ON", |
| 372 base::Bind(&LoggingNativeHandler::DcheckIsOn, base::Unretained(this))); |
370 } | 373 } |
371 | 374 |
372 v8::Handle<v8::Value> Check(const v8::Arguments& args) { | 375 v8::Handle<v8::Value> Check(const v8::Arguments& args) { |
373 bool check_value; | 376 bool check_value; |
374 std::string error_message; | 377 std::string error_message; |
375 ParseArgs(args, &check_value, &error_message); | 378 ParseArgs(args, &check_value, &error_message); |
376 CHECK(check_value) << error_message; | 379 CHECK(check_value) << error_message; |
377 return v8::Undefined(); | 380 return v8::Undefined(); |
378 } | 381 } |
379 | 382 |
380 v8::Handle<v8::Value> Dcheck(const v8::Arguments& args) { | 383 v8::Handle<v8::Value> Dcheck(const v8::Arguments& args) { |
381 bool check_value; | 384 bool check_value; |
382 std::string error_message; | 385 std::string error_message; |
383 ParseArgs(args, &check_value, &error_message); | 386 ParseArgs(args, &check_value, &error_message); |
384 DCHECK(check_value) << error_message; | 387 DCHECK(check_value) << error_message; |
385 return v8::Undefined(); | 388 return v8::Undefined(); |
386 } | 389 } |
387 | 390 |
| 391 v8::Handle<v8::Value> DcheckIsOn(const v8::Arguments& args) { |
| 392 return v8::Boolean::New(DCHECK_IS_ON()); |
| 393 } |
| 394 |
388 private: | 395 private: |
389 void ParseArgs(const v8::Arguments& args, | 396 void ParseArgs(const v8::Arguments& args, |
390 bool* check_value, | 397 bool* check_value, |
391 std::string* error_message) { | 398 std::string* error_message) { |
392 CHECK_LE(args.Length(), 2); | 399 CHECK_LE(args.Length(), 2); |
393 *check_value = args[0]->BooleanValue(); | 400 *check_value = args[0]->BooleanValue(); |
394 if (args.Length() == 2) | 401 if (args.Length() == 2) |
395 *error_message = "Error: " + std::string( | 402 *error_message = "Error: " + std::string( |
396 *v8::String::AsciiValue(args[1])); | 403 *v8::String::AsciiValue(args[1])); |
397 | 404 |
(...skipping 20 matching lines...) Expand all Loading... |
418 return dflt; | 425 return dflt; |
419 std::string ascii_value = *v8::String::AsciiValue(v8_string); | 426 std::string ascii_value = *v8::String::AsciiValue(v8_string); |
420 return ascii_value.empty() ? dflt : ascii_value; | 427 return ascii_value.empty() ? dflt : ascii_value; |
421 } | 428 } |
422 }; | 429 }; |
423 | 430 |
424 void InstallAppBindings(ModuleSystem* module_system, | 431 void InstallAppBindings(ModuleSystem* module_system, |
425 v8::Handle<v8::Object> chrome, | 432 v8::Handle<v8::Object> chrome, |
426 v8::Handle<v8::Object> chrome_hidden) { | 433 v8::Handle<v8::Object> chrome_hidden) { |
427 module_system->SetLazyField(chrome, "app", "app", "chromeApp"); | 434 module_system->SetLazyField(chrome, "app", "app", "chromeApp"); |
428 module_system->SetLazyField(chrome_hidden, "app", "app", | |
429 "chromeHiddenApp"); | |
430 } | 435 } |
431 | 436 |
432 void InstallWebstoreBindings(ModuleSystem* module_system, | 437 void InstallWebstoreBindings(ModuleSystem* module_system, |
433 v8::Handle<v8::Object> chrome, | 438 v8::Handle<v8::Object> chrome, |
434 v8::Handle<v8::Object> chrome_hidden) { | 439 v8::Handle<v8::Object> chrome_hidden) { |
435 module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore"); | 440 module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore"); |
436 module_system->SetLazyField(chrome_hidden, "webstore", "webstore", | 441 module_system->SetLazyField(chrome_hidden, "webstore", "webstore", |
437 "chromeHiddenWebstore"); | 442 "chromeHiddenWebstore"); |
438 } | 443 } |
439 | 444 |
| 445 // Calls a method |method_name| in a module |module_name| belonging to the |
| 446 // module system from |context|. Intended as a callback target from |
| 447 // ChromeV8ContextSet::ForEach. |
| 448 void CallModuleMethod(const std::string& module_name, |
| 449 const std::string& method_name, |
| 450 const base::ListValue* args, |
| 451 ChromeV8Context* context) { |
| 452 v8::HandleScope handle_scope; |
| 453 v8::Context::Scope context_scope(context->v8_context()); |
| 454 |
| 455 scoped_ptr<content::V8ValueConverter> converter( |
| 456 content::V8ValueConverter::create()); |
| 457 |
| 458 std::vector<v8::Handle<v8::Value> > arguments; |
| 459 for (base::ListValue::const_iterator it = args->begin(); it != args->end(); |
| 460 ++it) { |
| 461 arguments.push_back(converter->ToV8Value(*it, context->v8_context())); |
| 462 } |
| 463 |
| 464 context->module_system()->CallModuleMethod( |
| 465 module_name, method_name, &arguments); |
| 466 } |
| 467 |
440 } // namespace | 468 } // namespace |
441 | 469 |
442 Dispatcher::Dispatcher() | 470 Dispatcher::Dispatcher() |
443 : content_watcher_(new ContentWatcher(this)), | 471 : content_watcher_(new ContentWatcher(this)), |
444 is_webkit_initialized_(false), | 472 is_webkit_initialized_(false), |
445 webrequest_adblock_(false), | 473 webrequest_adblock_(false), |
446 webrequest_adblock_plus_(false), | 474 webrequest_adblock_plus_(false), |
447 webrequest_other_(false), | 475 webrequest_other_(false), |
448 source_map_(&ResourceBundle::GetSharedInstance()) { | 476 source_map_(&ResourceBundle::GetSharedInstance()) { |
449 const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); | 477 const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 for (size_t i = 0; i < names.size(); ++i) | 567 for (size_t i = 0; i < names.size(); ++i) |
540 function_names_.insert(names[i]); | 568 function_names_.insert(names[i]); |
541 } | 569 } |
542 | 570 |
543 void Dispatcher::OnSetChannel(int channel) { | 571 void Dispatcher::OnSetChannel(int channel) { |
544 Feature::SetCurrentChannel( | 572 Feature::SetCurrentChannel( |
545 static_cast<chrome::VersionInfo::Channel>(channel)); | 573 static_cast<chrome::VersionInfo::Channel>(channel)); |
546 } | 574 } |
547 | 575 |
548 void Dispatcher::OnMessageInvoke(const std::string& extension_id, | 576 void Dispatcher::OnMessageInvoke(const std::string& extension_id, |
| 577 const std::string& module_name, |
549 const std::string& function_name, | 578 const std::string& function_name, |
550 const base::ListValue& args, | 579 const base::ListValue& args, |
551 bool user_gesture) { | 580 bool user_gesture) { |
552 scoped_ptr<WebScopedUserGesture> web_user_gesture; | 581 InvokeModuleSystemMethod( |
553 if (user_gesture) { | 582 NULL, extension_id, module_name, function_name, args, user_gesture); |
554 web_user_gesture.reset(new WebScopedUserGesture); | |
555 } | |
556 | |
557 v8_context_set_.DispatchChromeHiddenMethod( | |
558 extension_id, function_name, args, NULL); | |
559 | |
560 // Reset the idle handler each time there's any activity like event or message | |
561 // dispatch, for which Invoke is the chokepoint. | |
562 if (is_extension_process_) { | |
563 RenderThread::Get()->ScheduleIdleHandler( | |
564 kInitialExtensionIdleHandlerDelayMs); | |
565 } | |
566 | |
567 // Tell the browser process when an event has been dispatched with a lazy | |
568 // background page active. | |
569 const Extension* extension = extensions_.GetByID(extension_id); | |
570 if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && | |
571 function_name == kEventDispatchFunction) { | |
572 RenderView* background_view = | |
573 ExtensionHelper::GetBackgroundPage(extension_id); | |
574 if (background_view) { | |
575 background_view->Send(new ExtensionHostMsg_EventAck( | |
576 background_view->GetRoutingID())); | |
577 } | |
578 } | |
579 } | 583 } |
580 | 584 |
581 void Dispatcher::OnDispatchOnConnect( | 585 void Dispatcher::OnDispatchOnConnect( |
582 int target_port_id, | 586 int target_port_id, |
583 const std::string& channel_name, | 587 const std::string& channel_name, |
584 const base::DictionaryValue& source_tab, | 588 const base::DictionaryValue& source_tab, |
585 const ExtensionMsg_ExternalConnectionInfo& info) { | 589 const ExtensionMsg_ExternalConnectionInfo& info) { |
586 MiscellaneousBindings::DispatchOnConnect( | 590 MiscellaneousBindings::DispatchOnConnect( |
587 v8_context_set_.GetAll(), | 591 v8_context_set_.GetAll(), |
588 target_port_id, channel_name, source_tab, | 592 target_port_id, channel_name, source_tab, |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS); | 868 source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS); |
865 source_map_.RegisterSource("test", IDR_TEST_CUSTOM_BINDINGS_JS); | 869 source_map_.RegisterSource("test", IDR_TEST_CUSTOM_BINDINGS_JS); |
866 | 870 |
867 // Libraries. | 871 // Libraries. |
868 source_map_.RegisterSource("contentWatcher", IDR_CONTENT_WATCHER_JS); | 872 source_map_.RegisterSource("contentWatcher", IDR_CONTENT_WATCHER_JS); |
869 source_map_.RegisterSource("imageUtil", IDR_IMAGE_UTIL_JS); | 873 source_map_.RegisterSource("imageUtil", IDR_IMAGE_UTIL_JS); |
870 source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS); | 874 source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS); |
871 source_map_.RegisterSource("schemaUtils", IDR_SCHEMA_UTILS_JS); | 875 source_map_.RegisterSource("schemaUtils", IDR_SCHEMA_UTILS_JS); |
872 source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS); | 876 source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS); |
873 source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS); | 877 source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS); |
| 878 source_map_.RegisterSource("unload_event", IDR_UNLOAD_EVENT_JS); |
874 source_map_.RegisterSource("utils", IDR_UTILS_JS); | 879 source_map_.RegisterSource("utils", IDR_UTILS_JS); |
875 source_map_.RegisterSource("entryIdManager", IDR_ENTRY_ID_MANAGER); | 880 source_map_.RegisterSource("entryIdManager", IDR_ENTRY_ID_MANAGER); |
876 | 881 |
877 // Custom bindings. | 882 // Custom bindings. |
878 source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS); | 883 source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS); |
879 source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS); | 884 source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS); |
880 source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS); | 885 source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS); |
881 source_map_.RegisterSource("bluetooth", IDR_BLUETOOTH_CUSTOM_BINDINGS_JS); | 886 source_map_.RegisterSource("bluetooth", IDR_BLUETOOTH_CUSTOM_BINDINGS_JS); |
882 source_map_.RegisterSource("browserAction", | 887 source_map_.RegisterSource("browserAction", |
883 IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); | 888 IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 switch (context_type) { | 1061 switch (context_type) { |
1057 case Feature::UNSPECIFIED_CONTEXT: | 1062 case Feature::UNSPECIFIED_CONTEXT: |
1058 case Feature::WEB_PAGE_CONTEXT: | 1063 case Feature::WEB_PAGE_CONTEXT: |
1059 // TODO(kalman): see comment below about ExtensionAPI. | 1064 // TODO(kalman): see comment below about ExtensionAPI. |
1060 InstallBindings(module_system.get(), v8_context, "app"); | 1065 InstallBindings(module_system.get(), v8_context, "app"); |
1061 InstallBindings(module_system.get(), v8_context, "webstore"); | 1066 InstallBindings(module_system.get(), v8_context, "webstore"); |
1062 break; | 1067 break; |
1063 case Feature::BLESSED_EXTENSION_CONTEXT: | 1068 case Feature::BLESSED_EXTENSION_CONTEXT: |
1064 case Feature::UNBLESSED_EXTENSION_CONTEXT: | 1069 case Feature::UNBLESSED_EXTENSION_CONTEXT: |
1065 case Feature::CONTENT_SCRIPT_CONTEXT: | 1070 case Feature::CONTENT_SCRIPT_CONTEXT: |
1066 if (extension && !extension->is_platform_app()) | |
1067 module_system->Require("miscellaneous_bindings"); | |
1068 module_system->Require("json"); // see paranoid comment in json.js | 1071 module_system->Require("json"); // see paranoid comment in json.js |
1069 | 1072 |
1070 // TODO(kalman): move this code back out of the switch and execute it | 1073 // TODO(kalman): move this code back out of the switch and execute it |
1071 // regardless of |context_type|. ExtensionAPI knows how to return the | 1074 // regardless of |context_type|. ExtensionAPI knows how to return the |
1072 // correct APIs, however, until it doesn't have a 2MB overhead we can't | 1075 // correct APIs, however, until it doesn't have a 2MB overhead we can't |
1073 // load it in every process. | 1076 // load it in every process. |
1074 RegisterSchemaGeneratedBindings(module_system.get(), context); | 1077 RegisterSchemaGeneratedBindings(module_system.get(), context); |
1075 break; | 1078 break; |
1076 } | 1079 } |
1077 | 1080 |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1342 RenderThread::Get()->Send( | 1345 RenderThread::Get()->Send( |
1343 new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id)); | 1346 new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id)); |
1344 } | 1347 } |
1345 | 1348 |
1346 void Dispatcher::OnSuspend(const std::string& extension_id) { | 1349 void Dispatcher::OnSuspend(const std::string& extension_id) { |
1347 // Dispatch the suspend event. This doesn't go through the standard event | 1350 // Dispatch the suspend event. This doesn't go through the standard event |
1348 // dispatch machinery because it requires special handling. We need to let | 1351 // dispatch machinery because it requires special handling. We need to let |
1349 // the browser know when we are starting and stopping the event dispatch, so | 1352 // the browser know when we are starting and stopping the event dispatch, so |
1350 // that it still considers the extension idle despite any activity the suspend | 1353 // that it still considers the extension idle despite any activity the suspend |
1351 // event creates. | 1354 // event creates. |
1352 base::ListValue args; | 1355 DispatchEvent(extension_id, kOnSuspendEvent); |
1353 args.Set(0, new base::StringValue(kOnSuspendEvent)); | |
1354 args.Set(1, new base::ListValue()); | |
1355 v8_context_set_.DispatchChromeHiddenMethod( | |
1356 extension_id, kEventDispatchFunction, args, NULL); | |
1357 | |
1358 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); | 1356 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); |
1359 } | 1357 } |
1360 | 1358 |
1361 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { | 1359 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { |
1362 base::ListValue args; | 1360 DispatchEvent(extension_id, kOnSuspendCanceledEvent); |
1363 args.Set(0, new base::StringValue(kOnSuspendCanceledEvent)); | |
1364 args.Set(1, new base::ListValue()); | |
1365 v8_context_set_.DispatchChromeHiddenMethod( | |
1366 extension_id, kEventDispatchFunction, args, NULL); | |
1367 } | 1361 } |
1368 | 1362 |
1369 Feature::Context Dispatcher::ClassifyJavaScriptContext( | 1363 Feature::Context Dispatcher::ClassifyJavaScriptContext( |
1370 const std::string& extension_id, | 1364 const std::string& extension_id, |
1371 int extension_group, | 1365 int extension_group, |
1372 const ExtensionURLInfo& url_info) { | 1366 const ExtensionURLInfo& url_info) { |
1373 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { | 1367 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { |
1374 return extensions_.Contains(extension_id) ? | 1368 return extensions_.Contains(extension_id) ? |
1375 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; | 1369 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; |
1376 } | 1370 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1452 "%s cannot be used within a sandboxed frame."; | 1446 "%s cannot be used within a sandboxed frame."; |
1453 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); | 1447 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); |
1454 v8::ThrowException( | 1448 v8::ThrowException( |
1455 v8::Exception::Error(v8::String::New(error_msg.c_str()))); | 1449 v8::Exception::Error(v8::String::New(error_msg.c_str()))); |
1456 return false; | 1450 return false; |
1457 } | 1451 } |
1458 | 1452 |
1459 return true; | 1453 return true; |
1460 } | 1454 } |
1461 | 1455 |
| 1456 void Dispatcher::DispatchEvent(const std::string& extension_id, |
| 1457 const std::string& event_name) const { |
| 1458 base::ListValue args; |
| 1459 args.Set(0, new base::StringValue(event_name)); |
| 1460 args.Set(1, new base::ListValue()); |
| 1461 v8_context_set_.ForEach( |
| 1462 extension_id, |
| 1463 NULL, // all render views |
| 1464 base::Bind(&CallModuleMethod, |
| 1465 kEventModule, |
| 1466 kEventDispatchFunction, |
| 1467 &args)); |
| 1468 } |
| 1469 |
| 1470 void Dispatcher::InvokeModuleSystemMethod( |
| 1471 content::RenderView* render_view, |
| 1472 const std::string& extension_id, |
| 1473 const std::string& module_name, |
| 1474 const std::string& function_name, |
| 1475 const base::ListValue& args, |
| 1476 bool user_gesture) { |
| 1477 scoped_ptr<WebScopedUserGesture> web_user_gesture; |
| 1478 if (user_gesture) |
| 1479 web_user_gesture.reset(new WebScopedUserGesture); |
| 1480 |
| 1481 v8_context_set_.ForEach( |
| 1482 extension_id, |
| 1483 render_view, |
| 1484 base::Bind(&CallModuleMethod, module_name, function_name, &args)); |
| 1485 |
| 1486 // Reset the idle handler each time there's any activity like event or message |
| 1487 // dispatch, for which Invoke is the chokepoint. |
| 1488 if (is_extension_process_) { |
| 1489 RenderThread::Get()->ScheduleIdleHandler( |
| 1490 kInitialExtensionIdleHandlerDelayMs); |
| 1491 } |
| 1492 |
| 1493 // Tell the browser process when an event has been dispatched with a lazy |
| 1494 // background page active. |
| 1495 const Extension* extension = extensions_.GetByID(extension_id); |
| 1496 if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && |
| 1497 module_name == kEventModule && |
| 1498 function_name == kEventDispatchFunction) { |
| 1499 RenderView* background_view = |
| 1500 ExtensionHelper::GetBackgroundPage(extension_id); |
| 1501 if (background_view) { |
| 1502 background_view->Send(new ExtensionHostMsg_EventAck( |
| 1503 background_view->GetRoutingID())); |
| 1504 } |
| 1505 } |
| 1506 } |
| 1507 |
1462 } // namespace extensions | 1508 } // namespace extensions |
OLD | NEW |