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

Side by Side Diff: chrome/renderer/extensions/extension_dispatcher.cc

Issue 9835039: Make app_custom_bindings.js lazily evaluated so it doesn't execute on every page load. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/extensions/extension_dispatcher.h ('k') | chrome/renderer/module_system.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/extension_dispatcher.h ('k') | chrome/renderer/module_system.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698