| 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/extension_dispatcher.h" | 5 #include "chrome/renderer/extensions/extension_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/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/string_piece.h" | 10 #include "base/string_piece.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 | 111 |
| 112 std::vector<std::string> components; | 112 std::vector<std::string> components; |
| 113 for (int i = 0; i < args.Length(); ++i) | 113 for (int i = 0; i < args.Length(); ++i) |
| 114 components.push_back(*v8::String::Utf8Value(args[i]->ToString())); | 114 components.push_back(*v8::String::Utf8Value(args[i]->ToString())); |
| 115 | 115 |
| 116 LOG(ERROR) << JoinString(components, ','); | 116 LOG(ERROR) << JoinString(components, ','); |
| 117 return v8::Undefined(); | 117 return v8::Undefined(); |
| 118 } | 118 } |
| 119 }; | 119 }; |
| 120 | 120 |
| 121 void InstallAppBindings(ModuleSystem* module_system, |
| 122 v8::Handle<v8::Object> chrome, |
| 123 v8::Handle<v8::Object> chrome_hidden) { |
| 124 module_system->SetLazyField(chrome, "app", "app", "chromeApp"); |
| 125 module_system->SetLazyField(chrome, "appNotifications", "app", |
| 126 "chromeAppNotifications"); |
| 127 module_system->SetLazyField(chrome_hidden, "app", "app", |
| 128 "chromeHiddenApp"); |
| 129 } |
| 130 |
| 131 void InstallWebstoreBindings(ModuleSystem* module_system, |
| 132 v8::Handle<v8::Object> chrome, |
| 133 v8::Handle<v8::Object> chrome_hidden) { |
| 134 module_system->SetLazyField(chrome, "webstore", "webstore", "chromeWebstore"); |
| 135 module_system->SetLazyField(chrome_hidden, "webstore", "webstore", |
| 136 "chromeHiddenWebstore"); |
| 137 } |
| 138 |
| 121 } | 139 } |
| 122 | 140 |
| 123 ExtensionDispatcher::ExtensionDispatcher() | 141 ExtensionDispatcher::ExtensionDispatcher() |
| 124 : is_webkit_initialized_(false), | 142 : is_webkit_initialized_(false), |
| 125 webrequest_adblock_(false), | 143 webrequest_adblock_(false), |
| 126 webrequest_adblock_plus_(false), | 144 webrequest_adblock_plus_(false), |
| 127 webrequest_other_(false), | 145 webrequest_other_(false), |
| 128 source_map_(&ResourceBundle::GetSharedInstance()) { | 146 source_map_(&ResourceBundle::GetSharedInstance()) { |
| 129 const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); | 147 const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); |
| 130 is_extension_process_ = | 148 is_extension_process_ = |
| 131 command_line.HasSwitch(switches::kExtensionProcess) || | 149 command_line.HasSwitch(switches::kExtensionProcess) || |
| 132 command_line.HasSwitch(switches::kSingleProcess); | 150 command_line.HasSwitch(switches::kSingleProcess); |
| 133 | 151 |
| 134 if (is_extension_process_) { | 152 if (is_extension_process_) { |
| 135 RenderThread::Get()->SetIdleNotificationDelayInMs( | 153 RenderThread::Get()->SetIdleNotificationDelayInMs( |
| 136 kInitialExtensionIdleHandlerDelayMs); | 154 kInitialExtensionIdleHandlerDelayMs); |
| 137 } | 155 } |
| 138 | 156 |
| 139 user_script_slave_.reset(new UserScriptSlave(&extensions_)); | 157 user_script_slave_.reset(new UserScriptSlave(&extensions_)); |
| 140 PopulateSourceMap(); | 158 PopulateSourceMap(); |
| 159 PopulateLazyBindingsMap(); |
| 141 } | 160 } |
| 142 | 161 |
| 143 ExtensionDispatcher::~ExtensionDispatcher() { | 162 ExtensionDispatcher::~ExtensionDispatcher() { |
| 144 } | 163 } |
| 145 | 164 |
| 146 bool ExtensionDispatcher::OnControlMessageReceived( | 165 bool ExtensionDispatcher::OnControlMessageReceived( |
| 147 const IPC::Message& message) { | 166 const IPC::Message& message) { |
| 148 bool handled = true; | 167 bool handled = true; |
| 149 IPC_BEGIN_MESSAGE_MAP(ExtensionDispatcher, message) | 168 IPC_BEGIN_MESSAGE_MAP(ExtensionDispatcher, message) |
| 150 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) | 169 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); | 440 IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); |
| 422 source_map_.RegisterSource("storage", IDR_STORAGE_CUSTOM_BINDINGS_JS); | 441 source_map_.RegisterSource("storage", IDR_STORAGE_CUSTOM_BINDINGS_JS); |
| 423 source_map_.RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS); | 442 source_map_.RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS); |
| 424 source_map_.RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS); | 443 source_map_.RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS); |
| 425 source_map_.RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS); | 444 source_map_.RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS); |
| 426 source_map_.RegisterSource("types", IDR_TYPES_CUSTOM_BINDINGS_JS); | 445 source_map_.RegisterSource("types", IDR_TYPES_CUSTOM_BINDINGS_JS); |
| 427 source_map_.RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS); | 446 source_map_.RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS); |
| 428 source_map_.RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS); | 447 source_map_.RegisterSource("webstore", IDR_WEBSTORE_CUSTOM_BINDINGS_JS); |
| 429 } | 448 } |
| 430 | 449 |
| 450 void ExtensionDispatcher::PopulateLazyBindingsMap() { |
| 451 lazy_bindings_map_["app"] = InstallAppBindings; |
| 452 lazy_bindings_map_["webstore"] = InstallWebstoreBindings; |
| 453 } |
| 454 |
| 455 void ExtensionDispatcher::InstallBindings(ModuleSystem* module_system, |
| 456 v8::Handle<v8::Context> v8_context, |
| 457 const std::string& api) { |
| 458 std::map<std::string, BindingInstaller>::const_iterator lazy_binding = |
| 459 lazy_bindings_map_.find(api); |
| 460 if (lazy_binding != lazy_bindings_map_.end()) { |
| 461 v8::Handle<v8::Object> global(v8_context->Global()); |
| 462 v8::Handle<v8::Object> chrome = |
| 463 global->Get(v8::String::New("chrome"))->ToObject(); |
| 464 v8::Handle<v8::Object> chrome_hidden = |
| 465 ChromeV8Context::GetOrCreateChromeHidden(v8_context)->ToObject(); |
| 466 (*lazy_binding->second)(module_system, chrome, chrome_hidden); |
| 467 } else { |
| 468 module_system->Require(api); |
| 469 } |
| 470 } |
| 471 |
| 431 void ExtensionDispatcher::DidCreateScriptContext( | 472 void ExtensionDispatcher::DidCreateScriptContext( |
| 432 WebFrame* frame, v8::Handle<v8::Context> v8_context, int extension_group, | 473 WebFrame* frame, v8::Handle<v8::Context> v8_context, int extension_group, |
| 433 int world_id) { | 474 int world_id) { |
| 434 // TODO(koz): If the caller didn't pass extension_group, use the last value. | 475 // TODO(koz): If the caller didn't pass extension_group, use the last value. |
| 435 if (extension_group == -1) | 476 if (extension_group == -1) |
| 436 extension_group = g_hack_extension_group; | 477 extension_group = g_hack_extension_group; |
| 437 | 478 |
| 438 std::string extension_id = GetExtensionID(frame, world_id); | 479 std::string extension_id = GetExtensionID(frame, world_id); |
| 439 | 480 |
| 440 const Extension* extension = extensions_.GetByID(extension_id); | 481 const Extension* extension = extensions_.GetByID(extension_id); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 453 UserScriptSlave::GetDataSourceURLForFrame(frame)); | 494 UserScriptSlave::GetDataSourceURLForFrame(frame)); |
| 454 | 495 |
| 455 Feature::Context context_type = | 496 Feature::Context context_type = |
| 456 ClassifyJavaScriptContext(extension_id, extension_group, url_info); | 497 ClassifyJavaScriptContext(extension_id, extension_group, url_info); |
| 457 | 498 |
| 458 ChromeV8Context* context = | 499 ChromeV8Context* context = |
| 459 new ChromeV8Context(v8_context, frame, extension_id, context_type); | 500 new ChromeV8Context(v8_context, frame, extension_id, context_type); |
| 460 v8_context_set_.Add(context); | 501 v8_context_set_.Add(context); |
| 461 | 502 |
| 462 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(&source_map_)); | 503 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(&source_map_)); |
| 504 // Enable natives in startup. |
| 505 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system.get()); |
| 506 |
| 463 RegisterNativeHandlers(module_system.get(), context); | 507 RegisterNativeHandlers(module_system.get(), context); |
| 464 | 508 |
| 465 module_system->RegisterNativeHandler("chrome_hidden", | 509 module_system->RegisterNativeHandler("chrome_hidden", |
| 466 scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler())); | 510 scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler())); |
| 467 module_system->RegisterNativeHandler("print", | 511 module_system->RegisterNativeHandler("print", |
| 468 scoped_ptr<NativeHandler>(new PrintNativeHandler())); | 512 scoped_ptr<NativeHandler>(new PrintNativeHandler())); |
| 469 | 513 |
| 470 int manifest_version = 1; | 514 int manifest_version = 1; |
| 471 if (extension) | 515 if (extension) |
| 472 manifest_version = extension->manifest_version(); | 516 manifest_version = extension->manifest_version(); |
| 473 | 517 |
| 474 // Create the 'chrome' variable if it doesn't already exist. | 518 // Create the 'chrome' variable if it doesn't already exist. |
| 475 { | 519 { |
| 476 v8::HandleScope handle_scope; | 520 v8::HandleScope handle_scope; |
| 477 v8::Handle<v8::String> chrome_string(v8::String::New("chrome")); | 521 v8::Handle<v8::String> chrome_string(v8::String::New("chrome")); |
| 478 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global()); | 522 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global()); |
| 479 if (global->Get(chrome_string)->IsUndefined()) | 523 if (global->Get(chrome_string)->IsUndefined()) |
| 480 global->Set(chrome_string, v8::Object::New()); | 524 global->Set(chrome_string, v8::Object::New()); |
| 481 } | 525 } |
| 482 | 526 |
| 483 // Loading JavaScript is expensive, so only run the full API bindings | 527 // Loading JavaScript is expensive, so only run the full API bindings |
| 484 // generation mechanisms in extension pages (NOT all web pages). | 528 // generation mechanisms in extension pages (NOT all web pages). |
| 485 switch (context_type) { | 529 switch (context_type) { |
| 486 case Feature::UNSPECIFIED_CONTEXT: | 530 case Feature::UNSPECIFIED_CONTEXT: |
| 487 case Feature::WEB_PAGE_CONTEXT: | 531 case Feature::WEB_PAGE_CONTEXT: |
| 488 // TODO(kalman): see comment below about ExtensionAPI. | 532 // TODO(kalman): see comment below about ExtensionAPI. |
| 489 module_system->Require("app"); | 533 InstallBindings(module_system.get(), v8_context, "app"); |
| 490 module_system->Require("webstore"); | 534 InstallBindings(module_system.get(), v8_context, "webstore"); |
| 491 break; | 535 break; |
| 492 | 536 |
| 493 case Feature::BLESSED_EXTENSION_CONTEXT: | 537 case Feature::BLESSED_EXTENSION_CONTEXT: |
| 494 case Feature::UNBLESSED_EXTENSION_CONTEXT: | 538 case Feature::UNBLESSED_EXTENSION_CONTEXT: |
| 495 case Feature::CONTENT_SCRIPT_CONTEXT: { | 539 case Feature::CONTENT_SCRIPT_CONTEXT: { |
| 496 module_system->Require("json_schema"); | 540 module_system->Require("json_schema"); |
| 497 module_system->Require("event_bindings"); | 541 module_system->Require("event_bindings"); |
| 498 module_system->Require("miscellaneous_bindings"); | 542 module_system->Require("miscellaneous_bindings"); |
| 499 module_system->Require("schema_generated_bindings"); | 543 module_system->Require("schema_generated_bindings"); |
| 500 module_system->Require("apitest"); | 544 module_system->Require("apitest"); |
| 501 | 545 |
| 502 // TODO(kalman): move this code back out of the switch and execute it | 546 // TODO(kalman): move this code back out of the switch and execute it |
| 503 // regardless of |context_type|. ExtensionAPI knows how to return the | 547 // regardless of |context_type|. ExtensionAPI knows how to return the |
| 504 // correct APIs, however, until it doesn't have a 2MB overhead we can't | 548 // correct APIs, however, until it doesn't have a 2MB overhead we can't |
| 505 // load it in every process. | 549 // load it in every process. |
| 506 scoped_ptr<std::set<std::string> > apis = | 550 scoped_ptr<std::set<std::string> > apis = |
| 507 ExtensionAPI::GetInstance()->GetAPIsForContext( | 551 ExtensionAPI::GetInstance()->GetAPIsForContext( |
| 508 context_type, extension, url_info.url()); | 552 context_type, extension, url_info.url()); |
| 509 for (std::set<std::string>::iterator i = apis->begin(); i != apis->end(); | 553 for (std::set<std::string>::iterator i = apis->begin(); i != apis->end(); |
| 510 ++i) { | 554 ++i) { |
| 511 module_system->Require(*i); | 555 InstallBindings(module_system.get(), v8_context, *i); |
| 512 } | 556 } |
| 513 | 557 |
| 514 break; | 558 break; |
| 515 } | 559 } |
| 516 } | 560 } |
| 517 | 561 |
| 518 // TODO(kalman): this is probably the most unfortunate thing I've ever had to | 562 // TODO(kalman): this is probably the most unfortunate thing I've ever had to |
| 519 // write. We really need to factor things differently to delete the concept | 563 // write. We really need to factor things differently to delete the concept |
| 520 // of a test extension ID. | 564 // of a test extension ID. |
| 521 if (IsTestExtensionId(extension_id)) { | 565 if (IsTestExtensionId(extension_id)) { |
| 522 module_system->Require("miscellaneous_bindings"); | 566 module_system->Require("miscellaneous_bindings"); |
| 523 module_system->Require("schema_generated_bindings"); | 567 module_system->Require("schema_generated_bindings"); |
| 524 module_system->Require("extension"); | 568 InstallBindings(module_system.get(), v8_context, "extension"); |
| 525 } | 569 } |
| 526 | 570 |
| 527 module_system->set_natives_enabled(false); | |
| 528 | |
| 529 context->set_module_system(module_system.Pass()); | 571 context->set_module_system(module_system.Pass()); |
| 530 | 572 |
| 531 context->DispatchOnLoadEvent( | 573 context->DispatchOnLoadEvent( |
| 532 is_extension_process_, | 574 is_extension_process_, |
| 533 ChromeRenderProcessObserver::is_incognito_process(), | 575 ChromeRenderProcessObserver::is_incognito_process(), |
| 534 manifest_version); | 576 manifest_version); |
| 535 | 577 |
| 536 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); | 578 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); |
| 537 } | 579 } |
| 538 | 580 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 return Feature::BLESSED_EXTENSION_CONTEXT; | 752 return Feature::BLESSED_EXTENSION_CONTEXT; |
| 711 | 753 |
| 712 if (extensions_.ExtensionBindingsAllowed(url_info)) | 754 if (extensions_.ExtensionBindingsAllowed(url_info)) |
| 713 return Feature::UNBLESSED_EXTENSION_CONTEXT; | 755 return Feature::UNBLESSED_EXTENSION_CONTEXT; |
| 714 | 756 |
| 715 if (url_info.url().is_valid()) | 757 if (url_info.url().is_valid()) |
| 716 return Feature::WEB_PAGE_CONTEXT; | 758 return Feature::WEB_PAGE_CONTEXT; |
| 717 | 759 |
| 718 return Feature::UNSPECIFIED_CONTEXT; | 760 return Feature::UNSPECIFIED_CONTEXT; |
| 719 } | 761 } |
| OLD | NEW |