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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 }; | 365 }; |
365 | 366 |
366 class LoggingNativeHandler : public ObjectBackedNativeHandler { | 367 class LoggingNativeHandler : public ObjectBackedNativeHandler { |
367 public: | 368 public: |
368 explicit LoggingNativeHandler(v8::Handle<v8::Context> context) | 369 explicit LoggingNativeHandler(v8::Handle<v8::Context> context) |
369 : ObjectBackedNativeHandler(context) { | 370 : ObjectBackedNativeHandler(context) { |
370 RouteFunction("DCHECK", | 371 RouteFunction("DCHECK", |
371 base::Bind(&LoggingNativeHandler::Dcheck, base::Unretained(this))); | 372 base::Bind(&LoggingNativeHandler::Dcheck, base::Unretained(this))); |
372 RouteFunction("CHECK", | 373 RouteFunction("CHECK", |
373 base::Bind(&LoggingNativeHandler::Check, base::Unretained(this))); | 374 base::Bind(&LoggingNativeHandler::Check, base::Unretained(this))); |
| 375 RouteFunction("DCHECK_IS_ON", |
| 376 base::Bind(&LoggingNativeHandler::DcheckIsOn, base::Unretained(this))); |
374 } | 377 } |
375 | 378 |
376 v8::Handle<v8::Value> Check(const v8::Arguments& args) { | 379 v8::Handle<v8::Value> Check(const v8::Arguments& args) { |
377 bool check_value; | 380 bool check_value; |
378 std::string error_message; | 381 std::string error_message; |
379 ParseArgs(args, &check_value, &error_message); | 382 ParseArgs(args, &check_value, &error_message); |
380 CHECK(check_value) << error_message; | 383 CHECK(check_value) << error_message; |
381 return v8::Undefined(); | 384 return v8::Undefined(); |
382 } | 385 } |
383 | 386 |
384 v8::Handle<v8::Value> Dcheck(const v8::Arguments& args) { | 387 v8::Handle<v8::Value> Dcheck(const v8::Arguments& args) { |
385 bool check_value; | 388 bool check_value; |
386 std::string error_message; | 389 std::string error_message; |
387 ParseArgs(args, &check_value, &error_message); | 390 ParseArgs(args, &check_value, &error_message); |
388 DCHECK(check_value) << error_message; | 391 DCHECK(check_value) << error_message; |
389 return v8::Undefined(); | 392 return v8::Undefined(); |
390 } | 393 } |
391 | 394 |
| 395 v8::Handle<v8::Value> DcheckIsOn(const v8::Arguments& args) { |
| 396 return v8::Boolean::New(DCHECK_IS_ON()); |
| 397 } |
| 398 |
392 private: | 399 private: |
393 void ParseArgs(const v8::Arguments& args, | 400 void ParseArgs(const v8::Arguments& args, |
394 bool* check_value, | 401 bool* check_value, |
395 std::string* error_message) { | 402 std::string* error_message) { |
396 CHECK_LE(args.Length(), 2); | 403 CHECK_LE(args.Length(), 2); |
397 *check_value = args[0]->BooleanValue(); | 404 *check_value = args[0]->BooleanValue(); |
398 if (args.Length() == 2) | 405 if (args.Length() == 2) |
399 *error_message = "Error: " + std::string( | 406 *error_message = "Error: " + std::string( |
400 *v8::String::AsciiValue(args[1])); | 407 *v8::String::AsciiValue(args[1])); |
401 | 408 |
(...skipping 20 matching lines...) Expand all Loading... |
422 return dflt; | 429 return dflt; |
423 std::string ascii_value = *v8::String::AsciiValue(v8_string); | 430 std::string ascii_value = *v8::String::AsciiValue(v8_string); |
424 return ascii_value.empty() ? dflt : ascii_value; | 431 return ascii_value.empty() ? dflt : ascii_value; |
425 } | 432 } |
426 }; | 433 }; |
427 | 434 |
428 void InstallAppBindings(ModuleSystem* module_system, | 435 void InstallAppBindings(ModuleSystem* module_system, |
429 v8::Handle<v8::Object> chrome, | 436 v8::Handle<v8::Object> chrome, |
430 v8::Handle<v8::Object> chrome_hidden) { | 437 v8::Handle<v8::Object> chrome_hidden) { |
431 module_system->SetLazyField(chrome, "app", "app", "chromeApp"); | 438 module_system->SetLazyField(chrome, "app", "app", "chromeApp"); |
432 module_system->SetLazyField(chrome_hidden, "app", "app", | |
433 "chromeHiddenApp"); | |
434 } | 439 } |
435 | 440 |
436 void InstallWebstoreBindings(ModuleSystem* module_system, | 441 void InstallWebstoreBindings(ModuleSystem* module_system, |
437 v8::Handle<v8::Object> chrome, | 442 v8::Handle<v8::Object> chrome, |
438 v8::Handle<v8::Object> chrome_hidden) { | 443 v8::Handle<v8::Object> chrome_hidden) { |
439 module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore"); | 444 module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore"); |
440 module_system->SetLazyField(chrome_hidden, "webstore", "webstore", | 445 module_system->SetLazyField(chrome_hidden, "webstore", "webstore", |
441 "chromeHiddenWebstore"); | 446 "chromeHiddenWebstore"); |
442 } | 447 } |
443 | 448 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 for (size_t i = 0; i < names.size(); ++i) | 548 for (size_t i = 0; i < names.size(); ++i) |
544 function_names_.insert(names[i]); | 549 function_names_.insert(names[i]); |
545 } | 550 } |
546 | 551 |
547 void Dispatcher::OnSetChannel(int channel) { | 552 void Dispatcher::OnSetChannel(int channel) { |
548 Feature::SetCurrentChannel( | 553 Feature::SetCurrentChannel( |
549 static_cast<chrome::VersionInfo::Channel>(channel)); | 554 static_cast<chrome::VersionInfo::Channel>(channel)); |
550 } | 555 } |
551 | 556 |
552 void Dispatcher::OnMessageInvoke(const std::string& extension_id, | 557 void Dispatcher::OnMessageInvoke(const std::string& extension_id, |
| 558 const std::string& module_name, |
553 const std::string& function_name, | 559 const std::string& function_name, |
554 const base::ListValue& args, | 560 const base::ListValue& args, |
555 bool user_gesture) { | 561 bool user_gesture) { |
556 scoped_ptr<WebScopedUserGesture> web_user_gesture; | 562 scoped_ptr<WebScopedUserGesture> web_user_gesture; |
557 if (user_gesture) { | 563 if (user_gesture) { |
558 web_user_gesture.reset(new WebScopedUserGesture); | 564 web_user_gesture.reset(new WebScopedUserGesture); |
559 } | 565 } |
560 | 566 |
561 v8_context_set_.DispatchChromeHiddenMethod( | 567 v8_context_set_.ForEach( |
562 extension_id, function_name, args, NULL); | 568 extension_id, |
| 569 NULL, // all render views |
| 570 base::Bind(&CallModuleMethod, module_name, function_name, &args)); |
563 | 571 |
564 // Reset the idle handler each time there's any activity like event or message | 572 // Reset the idle handler each time there's any activity like event or message |
565 // dispatch, for which Invoke is the chokepoint. | 573 // dispatch, for which Invoke is the chokepoint. |
566 if (is_extension_process_) { | 574 if (is_extension_process_) { |
567 RenderThread::Get()->ScheduleIdleHandler( | 575 RenderThread::Get()->ScheduleIdleHandler( |
568 kInitialExtensionIdleHandlerDelayMs); | 576 kInitialExtensionIdleHandlerDelayMs); |
569 } | 577 } |
570 | 578 |
571 // Tell the browser process when an event has been dispatched with a lazy | 579 // Tell the browser process when an event has been dispatched with a lazy |
572 // background page active. | 580 // background page active. |
573 const Extension* extension = extensions_.GetByID(extension_id); | 581 const Extension* extension = extensions_.GetByID(extension_id); |
574 if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && | 582 if (extension && BackgroundInfo::HasLazyBackgroundPage(extension) && |
| 583 module_name == kEventModule && |
575 function_name == kEventDispatchFunction) { | 584 function_name == kEventDispatchFunction) { |
576 RenderView* background_view = | 585 RenderView* background_view = |
577 ExtensionHelper::GetBackgroundPage(extension_id); | 586 ExtensionHelper::GetBackgroundPage(extension_id); |
578 if (background_view) { | 587 if (background_view) { |
579 background_view->Send(new ExtensionHostMsg_EventAck( | 588 background_view->Send(new ExtensionHostMsg_EventAck( |
580 background_view->GetRoutingID())); | 589 background_view->GetRoutingID())); |
581 } | 590 } |
582 } | 591 } |
583 } | 592 } |
584 | 593 |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS); | 879 source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS); |
871 source_map_.RegisterSource("test", IDR_TEST_CUSTOM_BINDINGS_JS); | 880 source_map_.RegisterSource("test", IDR_TEST_CUSTOM_BINDINGS_JS); |
872 | 881 |
873 // Libraries. | 882 // Libraries. |
874 source_map_.RegisterSource("contentWatcher", IDR_CONTENT_WATCHER_JS); | 883 source_map_.RegisterSource("contentWatcher", IDR_CONTENT_WATCHER_JS); |
875 source_map_.RegisterSource("imageUtil", IDR_IMAGE_UTIL_JS); | 884 source_map_.RegisterSource("imageUtil", IDR_IMAGE_UTIL_JS); |
876 source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS); | 885 source_map_.RegisterSource("lastError", IDR_LAST_ERROR_JS); |
877 source_map_.RegisterSource("schemaUtils", IDR_SCHEMA_UTILS_JS); | 886 source_map_.RegisterSource("schemaUtils", IDR_SCHEMA_UTILS_JS); |
878 source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS); | 887 source_map_.RegisterSource("sendRequest", IDR_SEND_REQUEST_JS); |
879 source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS); | 888 source_map_.RegisterSource("setIcon", IDR_SET_ICON_JS); |
| 889 source_map_.RegisterSource("unload_event", IDR_UNLOAD_EVENT_JS); |
880 source_map_.RegisterSource("utils", IDR_UTILS_JS); | 890 source_map_.RegisterSource("utils", IDR_UTILS_JS); |
881 source_map_.RegisterSource("entryIdManager", IDR_ENTRY_ID_MANAGER); | 891 source_map_.RegisterSource("entryIdManager", IDR_ENTRY_ID_MANAGER); |
882 | 892 |
883 // Custom bindings. | 893 // Custom bindings. |
884 source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS); | 894 source_map_.RegisterSource("app", IDR_APP_CUSTOM_BINDINGS_JS); |
885 source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS); | 895 source_map_.RegisterSource("app.runtime", IDR_APP_RUNTIME_CUSTOM_BINDINGS_JS); |
886 source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS); | 896 source_map_.RegisterSource("app.window", IDR_APP_WINDOW_CUSTOM_BINDINGS_JS); |
887 source_map_.RegisterSource("bluetooth", IDR_BLUETOOTH_CUSTOM_BINDINGS_JS); | 897 source_map_.RegisterSource("bluetooth", IDR_BLUETOOTH_CUSTOM_BINDINGS_JS); |
888 source_map_.RegisterSource("browserAction", | 898 source_map_.RegisterSource("browserAction", |
889 IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); | 899 IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 ExtensionURLInfo url_info(frame->document().securityOrigin(), | 1021 ExtensionURLInfo url_info(frame->document().securityOrigin(), |
1012 UserScriptSlave::GetDataSourceURLForFrame(frame)); | 1022 UserScriptSlave::GetDataSourceURLForFrame(frame)); |
1013 | 1023 |
1014 Feature::Context context_type = | 1024 Feature::Context context_type = |
1015 ClassifyJavaScriptContext(extension_id, extension_group, url_info); | 1025 ClassifyJavaScriptContext(extension_id, extension_group, url_info); |
1016 | 1026 |
1017 ChromeV8Context* context = | 1027 ChromeV8Context* context = |
1018 new ChromeV8Context(v8_context, frame, extension, context_type); | 1028 new ChromeV8Context(v8_context, frame, extension, context_type); |
1019 v8_context_set_.Add(context); | 1029 v8_context_set_.Add(context); |
1020 | 1030 |
1021 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(v8_context, | 1031 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context, |
1022 &source_map_)); | 1032 &source_map_)); |
1023 // Enable natives in startup. | 1033 // Enable natives in startup. |
1024 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system.get()); | 1034 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system.get()); |
1025 | 1035 |
1026 RegisterNativeHandlers(module_system.get(), context); | 1036 RegisterNativeHandlers(module_system.get(), context); |
1027 | 1037 |
1028 module_system->RegisterNativeHandler("chrome", | 1038 module_system->RegisterNativeHandler("chrome", |
1029 scoped_ptr<NativeHandler>(new ChromeNativeHandler(v8_context))); | 1039 scoped_ptr<NativeHandler>(new ChromeNativeHandler(v8_context))); |
1030 module_system->RegisterNativeHandler("chrome_hidden", | 1040 module_system->RegisterNativeHandler("chrome_hidden", |
1031 scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler(v8_context))); | 1041 scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler(v8_context))); |
(...skipping 30 matching lines...) Expand all Loading... |
1062 switch (context_type) { | 1072 switch (context_type) { |
1063 case Feature::UNSPECIFIED_CONTEXT: | 1073 case Feature::UNSPECIFIED_CONTEXT: |
1064 case Feature::WEB_PAGE_CONTEXT: | 1074 case Feature::WEB_PAGE_CONTEXT: |
1065 // TODO(kalman): see comment below about ExtensionAPI. | 1075 // TODO(kalman): see comment below about ExtensionAPI. |
1066 InstallBindings(module_system.get(), v8_context, "app"); | 1076 InstallBindings(module_system.get(), v8_context, "app"); |
1067 InstallBindings(module_system.get(), v8_context, "webstore"); | 1077 InstallBindings(module_system.get(), v8_context, "webstore"); |
1068 break; | 1078 break; |
1069 case Feature::BLESSED_EXTENSION_CONTEXT: | 1079 case Feature::BLESSED_EXTENSION_CONTEXT: |
1070 case Feature::UNBLESSED_EXTENSION_CONTEXT: | 1080 case Feature::UNBLESSED_EXTENSION_CONTEXT: |
1071 case Feature::CONTENT_SCRIPT_CONTEXT: | 1081 case Feature::CONTENT_SCRIPT_CONTEXT: |
1072 if (extension && !extension->is_platform_app()) | |
1073 module_system->Require("miscellaneous_bindings"); | |
1074 module_system->Require("json"); // see paranoid comment in json.js | 1082 module_system->Require("json"); // see paranoid comment in json.js |
1075 | 1083 |
1076 // TODO(kalman): move this code back out of the switch and execute it | 1084 // TODO(kalman): move this code back out of the switch and execute it |
1077 // regardless of |context_type|. ExtensionAPI knows how to return the | 1085 // regardless of |context_type|. ExtensionAPI knows how to return the |
1078 // correct APIs, however, until it doesn't have a 2MB overhead we can't | 1086 // correct APIs, however, until it doesn't have a 2MB overhead we can't |
1079 // load it in every process. | 1087 // load it in every process. |
1080 RegisterSchemaGeneratedBindings(module_system.get(), context); | 1088 RegisterSchemaGeneratedBindings(module_system.get(), context); |
1081 break; | 1089 break; |
1082 } | 1090 } |
1083 | 1091 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 RenderThread::Get()->Send( | 1355 RenderThread::Get()->Send( |
1348 new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id)); | 1356 new ExtensionHostMsg_ShouldSuspendAck(extension_id, sequence_id)); |
1349 } | 1357 } |
1350 | 1358 |
1351 void Dispatcher::OnSuspend(const std::string& extension_id) { | 1359 void Dispatcher::OnSuspend(const std::string& extension_id) { |
1352 // Dispatch the suspend event. This doesn't go through the standard event | 1360 // Dispatch the suspend event. This doesn't go through the standard event |
1353 // dispatch machinery because it requires special handling. We need to let | 1361 // dispatch machinery because it requires special handling. We need to let |
1354 // the browser know when we are starting and stopping the event dispatch, so | 1362 // the browser know when we are starting and stopping the event dispatch, so |
1355 // that it still considers the extension idle despite any activity the suspend | 1363 // that it still considers the extension idle despite any activity the suspend |
1356 // event creates. | 1364 // event creates. |
1357 base::ListValue args; | 1365 DispatchEvent(extension_id, kOnSuspendEvent); |
1358 args.Set(0, new base::StringValue(kOnSuspendEvent)); | |
1359 args.Set(1, new base::ListValue()); | |
1360 v8_context_set_.DispatchChromeHiddenMethod( | |
1361 extension_id, kEventDispatchFunction, args, NULL); | |
1362 | |
1363 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); | 1366 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); |
1364 } | 1367 } |
1365 | 1368 |
1366 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { | 1369 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { |
1367 base::ListValue args; | 1370 DispatchEvent(extension_id, kOnSuspendCanceledEvent); |
1368 args.Set(0, new base::StringValue(kOnSuspendCanceledEvent)); | |
1369 args.Set(1, new base::ListValue()); | |
1370 v8_context_set_.DispatchChromeHiddenMethod( | |
1371 extension_id, kEventDispatchFunction, args, NULL); | |
1372 } | 1371 } |
1373 | 1372 |
1374 Feature::Context Dispatcher::ClassifyJavaScriptContext( | 1373 Feature::Context Dispatcher::ClassifyJavaScriptContext( |
1375 const std::string& extension_id, | 1374 const std::string& extension_id, |
1376 int extension_group, | 1375 int extension_group, |
1377 const ExtensionURLInfo& url_info) { | 1376 const ExtensionURLInfo& url_info) { |
1378 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { | 1377 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { |
1379 return extensions_.Contains(extension_id) ? | 1378 return extensions_.Contains(extension_id) ? |
1380 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; | 1379 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; |
1381 } | 1380 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1457 "%s cannot be used within a sandboxed frame."; | 1456 "%s cannot be used within a sandboxed frame."; |
1458 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); | 1457 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); |
1459 v8::ThrowException( | 1458 v8::ThrowException( |
1460 v8::Exception::Error(v8::String::New(error_msg.c_str()))); | 1459 v8::Exception::Error(v8::String::New(error_msg.c_str()))); |
1461 return false; | 1460 return false; |
1462 } | 1461 } |
1463 | 1462 |
1464 return true; | 1463 return true; |
1465 } | 1464 } |
1466 | 1465 |
| 1466 void Dispatcher::DispatchEvent(const std::string& extension_id, |
| 1467 const std::string& event_name) const { |
| 1468 base::ListValue args; |
| 1469 args.Set(0, new base::StringValue(event_name)); |
| 1470 args.Set(1, new base::ListValue()); |
| 1471 v8_context_set_.ForEach( |
| 1472 extension_id, |
| 1473 NULL, // all render views |
| 1474 base::Bind(&CallModuleMethod, |
| 1475 kEventModule, |
| 1476 kEventDispatchFunction, |
| 1477 &args)); |
| 1478 } |
| 1479 |
| 1480 // static |
| 1481 void Dispatcher::CallModuleMethod(const std::string& module_name, |
| 1482 const std::string& method_name, |
| 1483 const base::ListValue* args, |
| 1484 ChromeV8Context* context) { |
| 1485 v8::HandleScope handle_scope; |
| 1486 v8::Context::Scope context_scope(context->v8_context()); |
| 1487 |
| 1488 scoped_ptr<content::V8ValueConverter> converter( |
| 1489 content::V8ValueConverter::create()); |
| 1490 |
| 1491 std::vector<v8::Handle<v8::Value> > arguments; |
| 1492 for (base::ListValue::const_iterator it = args->begin(); it != args->end(); |
| 1493 ++it) { |
| 1494 arguments.push_back(converter->ToV8Value(*it, context->v8_context())); |
| 1495 } |
| 1496 |
| 1497 context->module_system()->CallModuleMethod( |
| 1498 module_name, method_name, &arguments); |
| 1499 } |
| 1500 |
1467 } // namespace extensions | 1501 } // namespace extensions |
OLD | NEW |