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