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/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/string_piece.h" |
8 #include "chrome/common/child_process_logging.h" | 11 #include "chrome/common/child_process_logging.h" |
9 #include "chrome/common/chrome_switches.h" | 12 #include "chrome/common/chrome_switches.h" |
10 #include "chrome/common/extensions/extension.h" | 13 #include "chrome/common/extensions/extension.h" |
11 #include "chrome/common/extensions/extension_messages.h" | 14 #include "chrome/common/extensions/extension_messages.h" |
12 #include "chrome/common/extensions/extension_permission_set.h" | 15 #include "chrome/common/extensions/extension_permission_set.h" |
13 #include "chrome/common/url_constants.h" | 16 #include "chrome/common/url_constants.h" |
14 #include "chrome/renderer/chrome_render_process_observer.h" | 17 #include "chrome/renderer/chrome_render_process_observer.h" |
15 #include "chrome/renderer/extensions/app_bindings.h" | 18 #include "chrome/renderer/extensions/app_bindings.h" |
16 #include "chrome/renderer/extensions/chrome_v8_context.h" | 19 #include "chrome/renderer/extensions/chrome_v8_context.h" |
17 #include "chrome/renderer/extensions/chrome_v8_extension.h" | 20 #include "chrome/renderer/extensions/chrome_v8_extension.h" |
18 #include "chrome/renderer/extensions/custom_bindings_util.h" | 21 #include "chrome/renderer/extensions/custom_bindings_util.h" |
19 #include "chrome/renderer/extensions/event_bindings.h" | 22 #include "chrome/renderer/extensions/event_bindings.h" |
20 #include "chrome/renderer/extensions/extension_groups.h" | 23 #include "chrome/renderer/extensions/extension_groups.h" |
21 #include "chrome/renderer/extensions/miscellaneous_bindings.h" | 24 #include "chrome/renderer/extensions/miscellaneous_bindings.h" |
22 #include "chrome/renderer/extensions/schema_generated_bindings.h" | 25 #include "chrome/renderer/extensions/schema_generated_bindings.h" |
23 #include "chrome/renderer/extensions/user_script_slave.h" | 26 #include "chrome/renderer/extensions/user_script_slave.h" |
24 #include "chrome/renderer/extensions/webstore_bindings.h" | 27 #include "chrome/renderer/extensions/webstore_bindings.h" |
| 28 #include "chrome/renderer/module_system.h" |
| 29 #include "chrome/renderer/native_handler.h" |
| 30 #include "chrome/renderer/resource_bundle_source_map.h" |
25 #include "content/public/renderer/render_thread.h" | 31 #include "content/public/renderer/render_thread.h" |
26 #include "grit/renderer_resources.h" | 32 #include "grit/renderer_resources.h" |
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" | 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" |
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h" | 36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h" |
31 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | 37 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" |
32 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLReques
t.h" | 38 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLReques
t.h" |
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedUserGesture.
h" | 39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScopedUserGesture.
h" |
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
35 #include "ui/base/resource/resource_bundle.h" | 41 #include "ui/base/resource/resource_bundle.h" |
36 #include "v8/include/v8.h" | 42 #include "v8/include/v8.h" |
37 | 43 |
| 44 #include "chrome/renderer/extensions/chrome_private_custom_bindings.h" |
| 45 #include "chrome/renderer/extensions/context_menus_custom_bindings.h" |
| 46 #include "chrome/renderer/extensions/experimental.socket_custom_bindings.h" |
| 47 #include "chrome/renderer/extensions/extension_custom_bindings.h" |
| 48 #include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h" |
| 49 #include "chrome/renderer/extensions/file_browser_private_custom_bindings.h" |
| 50 #include "chrome/renderer/extensions/i18n_custom_bindings.h" |
| 51 #include "chrome/renderer/extensions/page_actions_custom_bindings.h" |
| 52 #include "chrome/renderer/extensions/page_capture_custom_bindings.h" |
| 53 #include "chrome/renderer/extensions/tabs_custom_bindings.h" |
| 54 #include "chrome/renderer/extensions/tts_custom_bindings.h" |
| 55 #include "chrome/renderer/extensions/web_request_custom_bindings.h" |
| 56 |
38 using content::RenderThread; | 57 using content::RenderThread; |
| 58 using extensions::ChromePrivateCustomBindings; |
| 59 using extensions::ContextMenusCustomBindings; |
| 60 using extensions::ExperimentalSocketCustomBindings; |
| 61 using extensions::ExtensionCustomBindings; |
| 62 using extensions::FileBrowserHandlerCustomBindings; |
| 63 using extensions::FileBrowserPrivateCustomBindings; |
| 64 using extensions::I18NCustomBindings; |
39 using extensions::MiscellaneousBindings; | 65 using extensions::MiscellaneousBindings; |
| 66 using extensions::PageActionsCustomBindings; |
| 67 using extensions::PageCaptureCustomBindings; |
40 using extensions::SchemaGeneratedBindings; | 68 using extensions::SchemaGeneratedBindings; |
| 69 using extensions::TTSCustomBindings; |
| 70 using extensions::TabsCustomBindings; |
| 71 using extensions::WebRequestCustomBindings; |
41 using WebKit::WebDataSource; | 72 using WebKit::WebDataSource; |
42 using WebKit::WebDocument; | 73 using WebKit::WebDocument; |
43 using WebKit::WebFrame; | 74 using WebKit::WebFrame; |
44 using WebKit::WebSecurityPolicy; | 75 using WebKit::WebSecurityPolicy; |
45 using WebKit::WebString; | 76 using WebKit::WebString; |
46 using WebKit::WebScopedUserGesture; | 77 using WebKit::WebScopedUserGesture; |
47 using WebKit::WebVector; | 78 using WebKit::WebVector; |
48 using WebKit::WebView; | 79 using WebKit::WebView; |
49 | 80 |
50 namespace util = extensions::custom_bindings_util; | 81 namespace util = extensions::custom_bindings_util; |
51 | 82 |
52 namespace { | 83 namespace { |
53 | 84 |
54 static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000; | 85 static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000; |
55 static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000; | 86 static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000; |
56 | 87 |
57 ChromeV8Context::ContextType ExtensionGroupToContextType(int extension_group) { | 88 ChromeV8Context::ContextType ExtensionGroupToContextType(int extension_group) { |
58 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) | 89 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) |
59 return ChromeV8Context::CONTENT_SCRIPT; | 90 return ChromeV8Context::CONTENT_SCRIPT; |
60 return ChromeV8Context::OTHER; | 91 return ChromeV8Context::OTHER; |
61 } | 92 } |
62 | 93 |
| 94 class ChromeHiddenNativeHandler : public NativeHandler { |
| 95 public: |
| 96 ChromeHiddenNativeHandler() { |
| 97 RouteFunction("GetChromeHidden", |
| 98 base::Bind(&ChromeHiddenNativeHandler::GetChromeHidden, |
| 99 base::Unretained(this))); |
| 100 } |
| 101 |
| 102 v8::Handle<v8::Value> GetChromeHidden(const v8::Arguments& args) { |
| 103 return ChromeV8Context::GetOrCreateChromeHidden(v8::Context::GetCurrent()); |
| 104 } |
| 105 }; |
| 106 |
| 107 class PrintNativeHandler : public NativeHandler { |
| 108 public: |
| 109 PrintNativeHandler() { |
| 110 RouteFunction("Print", |
| 111 base::Bind(&PrintNativeHandler::Print, |
| 112 base::Unretained(this))); |
| 113 } |
| 114 |
| 115 v8::Handle<v8::Value> Print(const v8::Arguments& args) { |
| 116 if (args.Length() < 1) |
| 117 return v8::Undefined(); |
| 118 |
| 119 std::vector<std::string> components; |
| 120 for (int i = 0; i < args.Length(); ++i) |
| 121 components.push_back(*v8::String::Utf8Value(args[i]->ToString())); |
| 122 |
| 123 LOG(ERROR) << JoinString(components, ','); |
| 124 return v8::Undefined(); |
| 125 } |
| 126 }; |
| 127 |
| 128 class ContextInfoNativeHandler : public NativeHandler { |
| 129 public: |
| 130 explicit ContextInfoNativeHandler(ExtensionDispatcher* extension_dispatcher, |
| 131 bool is_bindings_allowed, |
| 132 WebKit::WebFrame* frame, |
| 133 int world_id) |
| 134 : extension_dispatcher_(extension_dispatcher), |
| 135 is_bindings_allowed_(is_bindings_allowed), |
| 136 frame_(frame), |
| 137 world_id_(world_id) { |
| 138 RouteFunction("IsBindingsAllowed", |
| 139 base::Bind(&ContextInfoNativeHandler::IsBindingsAllowed, |
| 140 base::Unretained(this))); |
| 141 RouteFunction("IsAPIAllowed", |
| 142 base::Bind(&ContextInfoNativeHandler::IsAPIAllowed, |
| 143 base::Unretained(this))); |
| 144 } |
| 145 |
| 146 v8::Handle<v8::Value> IsBindingsAllowed(const v8::Arguments& args) { |
| 147 return v8::Boolean::New(is_bindings_allowed_); |
| 148 } |
| 149 |
| 150 v8::Handle<v8::Value> IsAPIAllowed(const v8::Arguments& args) { |
| 151 std::string custom_api_name = *v8::String::AsciiValue(args[0]->ToString()); |
| 152 return v8::Boolean::New(extension_dispatcher_->AllowCustomAPI( |
| 153 frame_, custom_api_name, world_id_)); |
| 154 } |
| 155 |
| 156 private: |
| 157 ExtensionDispatcher* extension_dispatcher_; |
| 158 bool is_bindings_allowed_; |
| 159 WebKit::WebFrame* frame_; |
| 160 int world_id_; |
| 161 }; |
| 162 |
63 } | 163 } |
64 | 164 |
65 ExtensionDispatcher::ExtensionDispatcher() | 165 ExtensionDispatcher::ExtensionDispatcher() |
66 : is_webkit_initialized_(false), | 166 : is_webkit_initialized_(false), |
67 webrequest_adblock_(false), | 167 webrequest_adblock_(false), |
68 webrequest_adblock_plus_(false), | 168 webrequest_adblock_plus_(false), |
69 webrequest_other_(false) { | 169 webrequest_other_(false), |
| 170 source_map_(&ResourceBundle::GetSharedInstance()) { |
70 const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); | 171 const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); |
71 is_extension_process_ = | 172 is_extension_process_ = |
72 command_line.HasSwitch(switches::kExtensionProcess) || | 173 command_line.HasSwitch(switches::kExtensionProcess) || |
73 command_line.HasSwitch(switches::kSingleProcess); | 174 command_line.HasSwitch(switches::kSingleProcess); |
74 | 175 |
75 if (is_extension_process_) { | 176 if (is_extension_process_) { |
76 RenderThread::Get()->SetIdleNotificationDelayInMs( | 177 RenderThread::Get()->SetIdleNotificationDelayInMs( |
77 kInitialExtensionIdleHandlerDelayMs); | 178 kInitialExtensionIdleHandlerDelayMs); |
78 } | 179 } |
79 | 180 |
80 user_script_slave_.reset(new UserScriptSlave(&extensions_)); | 181 user_script_slave_.reset(new UserScriptSlave(&extensions_)); |
| 182 PopulateSourceMap(); |
81 } | 183 } |
82 | 184 |
83 ExtensionDispatcher::~ExtensionDispatcher() { | 185 ExtensionDispatcher::~ExtensionDispatcher() { |
84 } | 186 } |
85 | 187 |
86 bool ExtensionDispatcher::OnControlMessageReceived( | 188 bool ExtensionDispatcher::OnControlMessageReceived( |
87 const IPC::Message& message) { | 189 const IPC::Message& message) { |
88 bool handled = true; | 190 bool handled = true; |
89 IPC_BEGIN_MESSAGE_MAP(ExtensionDispatcher, message) | 191 IPC_BEGIN_MESSAGE_MAP(ExtensionDispatcher, message) |
90 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) | 192 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) |
(...skipping 17 matching lines...) Expand all Loading... |
108 | 210 |
109 void ExtensionDispatcher::WebKitInitialized() { | 211 void ExtensionDispatcher::WebKitInitialized() { |
110 // For extensions, we want to ensure we call the IdleHandler every so often, | 212 // For extensions, we want to ensure we call the IdleHandler every so often, |
111 // even if the extension keeps up activity. | 213 // even if the extension keeps up activity. |
112 if (is_extension_process_) { | 214 if (is_extension_process_) { |
113 forced_idle_timer_.Start(FROM_HERE, | 215 forced_idle_timer_.Start(FROM_HERE, |
114 base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs), | 216 base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs), |
115 RenderThread::Get(), &RenderThread::IdleHandler); | 217 RenderThread::Get(), &RenderThread::IdleHandler); |
116 } | 218 } |
117 | 219 |
118 RegisterExtension(new AppBindings(this), false); | |
119 RegisterExtension(new WebstoreBindings(this), false); | |
120 | |
121 // Add v8 extensions related to chrome extensions. | |
122 RegisterExtension(new ChromeV8Extension( | |
123 "extensions/json_schema.js", IDR_JSON_SCHEMA_JS, NULL), true); | |
124 RegisterExtension(EventBindings::Get(this), true); | |
125 RegisterExtension(MiscellaneousBindings::Get(this), true); | |
126 RegisterExtension(SchemaGeneratedBindings::Get(this), true); | |
127 RegisterExtension(new ChromeV8Extension( | |
128 "extensions/apitest.js", IDR_EXTENSION_APITEST_JS, NULL), true); | |
129 | |
130 std::vector<v8::Extension*> custom_bindings = util::GetAll(this); | |
131 for (std::vector<v8::Extension*>::iterator it = custom_bindings.begin(); | |
132 it != custom_bindings.end(); ++it) { | |
133 RegisterExtension(*it, true); | |
134 } | |
135 | |
136 // Initialize host permissions for any extensions that were activated before | 220 // Initialize host permissions for any extensions that were activated before |
137 // WebKit was initialized. | 221 // WebKit was initialized. |
138 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); | 222 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); |
139 iter != active_extension_ids_.end(); ++iter) { | 223 iter != active_extension_ids_.end(); ++iter) { |
140 const Extension* extension = extensions_.GetByID(*iter); | 224 const Extension* extension = extensions_.GetByID(*iter); |
141 if (extension) | 225 if (extension) |
142 InitOriginPermissions(extension); | 226 InitOriginPermissions(extension); |
143 } | 227 } |
144 | 228 |
145 is_webkit_initialized_ = true; | 229 is_webkit_initialized_ = true; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 static int g_hack_extension_group = 0; | 377 static int g_hack_extension_group = 0; |
294 | 378 |
295 } | 379 } |
296 | 380 |
297 bool ExtensionDispatcher::AllowScriptExtension( | 381 bool ExtensionDispatcher::AllowScriptExtension( |
298 WebFrame* frame, | 382 WebFrame* frame, |
299 const std::string& v8_extension_name, | 383 const std::string& v8_extension_name, |
300 int extension_group, | 384 int extension_group, |
301 int world_id) { | 385 int world_id) { |
302 g_hack_extension_group = extension_group; | 386 g_hack_extension_group = extension_group; |
| 387 return true; |
| 388 } |
303 | 389 |
304 // NULL in unit tests. | 390 bool ExtensionDispatcher::AllowCustomAPI( |
305 if (!RenderThread::Get()) | 391 WebFrame* frame, |
| 392 const std::string& custom_binding_api_name, |
| 393 int world_id) { |
| 394 std::string extension_id = GetExtensionID(frame, world_id); |
| 395 if (IsTestExtensionId(extension_id)) |
306 return true; | 396 return true; |
| 397 const Extension* extension = extensions_.GetByID(extension_id); |
| 398 if (!extension) { |
| 399 // This can happen when a resource is blocked due to CSP; a valid |
| 400 // chrome-extension:// URL is navigated to, so it passes the initial |
| 401 // checks, but the URL gets changed to "chrome-extension://invalid" |
| 402 // afterwards (see chrome_content_renderer_client.cc). An extension |
| 403 // page still gets loaded, just for the extension with ID "invalid", |
| 404 // which of course isn't found so GetById extension will be NULL. |
| 405 // |
| 406 // Reference: http://crbug.com/111614. |
| 407 CHECK_EQ("invalid", extension_id); |
| 408 return false; |
| 409 } |
| 410 return util::AllowAPIInjection( |
| 411 custom_binding_api_name, *extension, this); |
| 412 } |
307 | 413 |
308 // If we don't know about it, it was added by WebCore, so we should allow it. | 414 void ExtensionDispatcher::RegisterNativeHandlers(ModuleSystem* module_system, |
309 if (!RenderThread::Get()->IsRegisteredExtension(v8_extension_name)) | 415 ChromeV8Context* context) { |
310 return true; | 416 module_system->RegisterNativeHandler("app", |
| 417 scoped_ptr<NativeHandler>(new AppBindings(this, context))); |
| 418 module_system->RegisterNativeHandler("webstore", |
| 419 scoped_ptr<NativeHandler>(new WebstoreBindings(this, context))); |
| 420 module_system->RegisterNativeHandler("event_bindings", |
| 421 scoped_ptr<NativeHandler>(EventBindings::Get(this))); |
| 422 module_system->RegisterNativeHandler("miscellaneous_bindings", |
| 423 scoped_ptr<NativeHandler>(MiscellaneousBindings::Get(this))); |
| 424 module_system->RegisterNativeHandler("schema_generated_bindings", |
| 425 scoped_ptr<NativeHandler>(SchemaGeneratedBindings::Get(this))); |
311 | 426 |
312 // If the V8 extension is not restricted, allow it to run anywhere. | 427 // Custom bindings. |
313 if (!restricted_v8_extensions_.count(v8_extension_name)) | 428 module_system->RegisterNativeHandler("chrome_private", |
314 return true; | 429 scoped_ptr<NativeHandler>( |
| 430 new ChromePrivateCustomBindings(this))); |
| 431 module_system->RegisterNativeHandler("context_menus", |
| 432 scoped_ptr<NativeHandler>(new ContextMenusCustomBindings())); |
| 433 module_system->RegisterNativeHandler("extension", |
| 434 scoped_ptr<NativeHandler>( |
| 435 new ExtensionCustomBindings(this))); |
| 436 module_system->RegisterNativeHandler("experimental_socket", |
| 437 scoped_ptr<NativeHandler>(new ExperimentalSocketCustomBindings())); |
| 438 module_system->RegisterNativeHandler("file_browser_handler", |
| 439 scoped_ptr<NativeHandler>(new FileBrowserHandlerCustomBindings())); |
| 440 module_system->RegisterNativeHandler("file_browser_private", |
| 441 scoped_ptr<NativeHandler>(new FileBrowserPrivateCustomBindings())); |
| 442 module_system->RegisterNativeHandler("i18n", |
| 443 scoped_ptr<NativeHandler>(new I18NCustomBindings())); |
| 444 module_system->RegisterNativeHandler("page_actions", |
| 445 scoped_ptr<NativeHandler>( |
| 446 new PageActionsCustomBindings(this))); |
| 447 module_system->RegisterNativeHandler("page_capture", |
| 448 scoped_ptr<NativeHandler>(new PageCaptureCustomBindings())); |
| 449 module_system->RegisterNativeHandler("tabs", |
| 450 scoped_ptr<NativeHandler>(new TabsCustomBindings())); |
| 451 module_system->RegisterNativeHandler("tts", |
| 452 scoped_ptr<NativeHandler>(new TTSCustomBindings())); |
| 453 module_system->RegisterNativeHandler("web_request", |
| 454 scoped_ptr<NativeHandler>(new WebRequestCustomBindings())); |
| 455 } |
315 | 456 |
316 // Extension-only bindings should be restricted to content scripts and | 457 void ExtensionDispatcher::PopulateSourceMap() { |
317 // extension-blessed URLs. | 458 source_map_.RegisterSource("app", IDR_APP_BINDINGS_JS); |
318 ChromeV8Context::ContextType context_type = | 459 source_map_.RegisterSource("webstore", IDR_WEBSTORE_BINDINGS_JS); |
319 ExtensionGroupToContextType(extension_group); | 460 source_map_.RegisterSource("event_bindings", IDR_EVENT_BINDINGS_JS); |
| 461 source_map_.RegisterSource("miscellaneous_bindings", |
| 462 IDR_MISCELLANEOUS_BINDINGS_JS); |
| 463 source_map_.RegisterSource("schema_generated_bindings", |
| 464 IDR_SCHEMA_GENERATED_BINDINGS_JS); |
| 465 source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS); |
| 466 source_map_.RegisterSource("apitest", IDR_EXTENSION_APITEST_JS); |
| 467 source_map_.RegisterSource("setup_bindings", IDR_SETUP_BINDINGS_JS); |
320 | 468 |
321 if (context_type == ChromeV8Context::CONTENT_SCRIPT || | 469 // Custom bindings. |
322 extensions_.ExtensionBindingsAllowed(ExtensionURLInfo( | 470 source_map_.RegisterSource("browserAction", |
323 frame->document().securityOrigin(), | 471 IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); |
324 UserScriptSlave::GetDataSourceURLForFrame(frame)))) { | 472 source_map_.RegisterSource("chromePrivate", |
325 // If the extension is a custom API binding, only allow if the extension | 473 IDR_CHROME_PRIVATE_CUSTOM_BINDINGS_JS); |
326 // has permission to use the API. | 474 source_map_.RegisterSource("contentSettings", |
327 std::string custom_binding_api_name = util::GetAPIName(v8_extension_name); | 475 IDR_CONTENT_SETTINGS_CUSTOM_BINDINGS_JS); |
328 if (!custom_binding_api_name.empty()) { | 476 source_map_.RegisterSource("contextMenus", |
329 std::string extension_id = GetExtensionID(frame, world_id); | 477 IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS); |
330 const Extension* extension = extensions_.GetByID(extension_id); | 478 source_map_.RegisterSource("devtools", IDR_DEVTOOLS_CUSTOM_BINDINGS_JS); |
331 if (!extension) { | 479 source_map_.RegisterSource("experimental.declarative", |
332 // This can happen when a resource is blocked due to CSP; a valid | 480 IDR_EXPERIMENTAL_DECLARATIVE_CUSTOM_BINDINGS_JS); |
333 // chrome-extension:// URL is navigated to, so it passes the initial | 481 source_map_.RegisterSource("experimental.socket", |
334 // checks, but the URL gets changed to "chrome-extension://invalid" | 482 IDR_EXPERIMENTAL_SOCKET_CUSTOM_BINDINGS_JS); |
335 // afterwards (see chrome_content_renderer_client.cc). An extension | 483 source_map_.RegisterSource("extension", IDR_EXTENSION_CUSTOM_BINDINGS_JS); |
336 // page still gets loaded, just for the extension with ID "invalid", | 484 source_map_.RegisterSource("fileBrowserHandler", |
337 // which of course isn't found so GetById extension will be NULL. | 485 IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS); |
338 // | 486 source_map_.RegisterSource("fileBrowserPrivate", |
339 // Reference: http://crbug.com/111614. | 487 IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS); |
340 CHECK_EQ("invalid", extension_id); | 488 source_map_.RegisterSource("i18n", IDR_I18N_CUSTOM_BINDINGS_JS); |
341 return false; | 489 source_map_.RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS); |
342 } | 490 source_map_.RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS); |
343 return util::AllowAPIInjection(custom_binding_api_name, *extension, this); | 491 source_map_.RegisterSource("pageActions", |
344 } | 492 IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS); |
345 | 493 source_map_.RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS); |
346 return true; | 494 source_map_.RegisterSource("pageCapture", |
347 } | 495 IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); |
348 | 496 source_map_.RegisterSource("storage", IDR_STORAGE_CUSTOM_BINDINGS_JS); |
349 return false; | 497 source_map_.RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS); |
| 498 source_map_.RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS); |
| 499 source_map_.RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS); |
| 500 source_map_.RegisterSource("types", IDR_TYPES_CUSTOM_BINDINGS_JS); |
| 501 source_map_.RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS); |
350 } | 502 } |
351 | 503 |
352 void ExtensionDispatcher::DidCreateScriptContext( | 504 void ExtensionDispatcher::DidCreateScriptContext( |
353 WebFrame* frame, v8::Handle<v8::Context> v8_context, int extension_group, | 505 WebFrame* frame, v8::Handle<v8::Context> v8_context, int extension_group, |
354 int world_id) { | 506 int world_id) { |
355 // TODO(koz): If the caller didn't pass extension_group, use the last value. | 507 // TODO(koz): If the caller didn't pass extension_group, use the last value. |
356 if (extension_group == -1) | 508 if (extension_group == -1) |
357 extension_group = g_hack_extension_group; | 509 extension_group = g_hack_extension_group; |
| 510 |
| 511 std::string extension_id = GetExtensionID(frame, world_id); |
358 ChromeV8Context* context = | 512 ChromeV8Context* context = |
359 new ChromeV8Context( | 513 new ChromeV8Context( |
360 v8_context, | 514 v8_context, |
361 frame, | 515 frame, |
362 GetExtensionID(frame, world_id), | 516 extension_id, |
363 ExtensionGroupToContextType(extension_group)); | 517 ExtensionGroupToContextType(extension_group)); |
364 v8_context_set_.Add(context); | 518 v8_context_set_.Add(context); |
365 | 519 |
| 520 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(&source_map_)); |
| 521 RegisterNativeHandlers(module_system.get(), context); |
| 522 |
| 523 bool is_bindings_allowed = |
| 524 IsTestExtensionId(extension_id) || |
| 525 context->context_type() == ChromeV8Context::CONTENT_SCRIPT || |
| 526 extensions_.ExtensionBindingsAllowed(ExtensionURLInfo( |
| 527 frame->document().securityOrigin(), |
| 528 UserScriptSlave::GetDataSourceURLForFrame(frame))); |
| 529 |
| 530 module_system->RegisterNativeHandler("chrome_hidden", |
| 531 scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler())); |
| 532 module_system->RegisterNativeHandler("context_info", |
| 533 scoped_ptr<NativeHandler>(new ContextInfoNativeHandler( |
| 534 this, |
| 535 is_bindings_allowed, |
| 536 frame, |
| 537 world_id))); |
| 538 module_system->RegisterNativeHandler("print", |
| 539 scoped_ptr<NativeHandler>(new PrintNativeHandler())); |
| 540 |
366 const Extension* extension = extensions_.GetByID(context->extension_id()); | 541 const Extension* extension = extensions_.GetByID(context->extension_id()); |
367 int manifest_version = 1; | 542 int manifest_version = 1; |
368 if (extension) | 543 if (extension) |
369 manifest_version = extension->manifest_version(); | 544 manifest_version = extension->manifest_version(); |
370 | 545 |
| 546 // Create the 'chrome' variable if it doesn't already exist. |
| 547 { |
| 548 v8::HandleScope handle_scope; |
| 549 v8::Handle<v8::String> chrome_string(v8::String::New("chrome")); |
| 550 v8::Handle<v8::Object> global(v8::Context::GetCurrent()->Global()); |
| 551 if (global->Get(chrome_string)->IsUndefined()) |
| 552 global->Set(chrome_string, v8::Object::New()); |
| 553 } |
| 554 module_system->Require("app"); |
| 555 module_system->Require("webstore"); |
| 556 if (is_bindings_allowed) { |
| 557 module_system->Require("setup_bindings"); |
| 558 } |
| 559 module_system->set_natives_enabled(false); |
| 560 |
| 561 context->set_module_system(module_system.Pass()); |
| 562 |
371 context->DispatchOnLoadEvent( | 563 context->DispatchOnLoadEvent( |
372 is_extension_process_, | 564 is_extension_process_, |
373 ChromeRenderProcessObserver::is_incognito_process(), | 565 ChromeRenderProcessObserver::is_incognito_process(), |
374 manifest_version); | 566 manifest_version); |
375 | 567 |
376 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); | 568 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); |
377 } | 569 } |
378 | 570 |
379 std::string ExtensionDispatcher::GetExtensionID(WebFrame* frame, int world_id) { | 571 std::string ExtensionDispatcher::GetExtensionID(WebFrame* frame, int world_id) { |
380 if (!test_extension_id_.empty()) { | 572 if (!test_extension_id_.empty()) { |
(...skipping 10 matching lines...) Expand all Loading... |
391 } | 583 } |
392 | 584 |
393 void ExtensionDispatcher::WillReleaseScriptContext( | 585 void ExtensionDispatcher::WillReleaseScriptContext( |
394 WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { | 586 WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { |
395 ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context); | 587 ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context); |
396 if (!context) | 588 if (!context) |
397 return; | 589 return; |
398 | 590 |
399 context->DispatchOnUnloadEvent(); | 591 context->DispatchOnUnloadEvent(); |
400 | 592 |
401 ChromeV8Extension::InstanceSet extensions = ChromeV8Extension::GetAll(); | |
402 for (ChromeV8Extension::InstanceSet::const_iterator iter = extensions.begin(); | |
403 iter != extensions.end(); ++iter) { | |
404 (*iter)->ContextWillBeReleased(context); | |
405 } | |
406 | |
407 v8_context_set_.Remove(context); | 593 v8_context_set_.Remove(context); |
408 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); | 594 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); |
409 } | 595 } |
410 | 596 |
411 void ExtensionDispatcher::SetTestExtensionId(const std::string& id) { | 597 void ExtensionDispatcher::SetTestExtensionId(const std::string& id) { |
412 test_extension_id_ = id; | 598 test_extension_id_ = id; |
413 } | 599 } |
414 | 600 |
415 bool ExtensionDispatcher::IsTestExtensionId(const std::string& id) { | 601 bool ExtensionDispatcher::IsTestExtensionId(const std::string& id) { |
416 return id == test_extension_id_; | 602 return !test_extension_id_.empty() && id == test_extension_id_; |
417 } | 603 } |
418 | 604 |
419 void ExtensionDispatcher::OnActivateApplication( | 605 void ExtensionDispatcher::OnActivateApplication( |
420 const std::string& extension_id) { | 606 const std::string& extension_id) { |
421 active_application_ids_.insert(extension_id); | 607 active_application_ids_.insert(extension_id); |
422 } | 608 } |
423 | 609 |
424 void ExtensionDispatcher::OnActivateExtension( | 610 void ExtensionDispatcher::OnActivateExtension( |
425 const std::string& extension_id) { | 611 const std::string& extension_id) { |
426 active_extension_ids_.insert(extension_id); | 612 active_extension_ids_.insert(extension_id); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 webrequest_adblock_ = adblock; | 727 webrequest_adblock_ = adblock; |
542 webrequest_adblock_plus_ = adblock_plus; | 728 webrequest_adblock_plus_ = adblock_plus; |
543 webrequest_other_ = other; | 729 webrequest_other_ = other; |
544 } | 730 } |
545 | 731 |
546 void ExtensionDispatcher::OnShouldClose(const std::string& extension_id, | 732 void ExtensionDispatcher::OnShouldClose(const std::string& extension_id, |
547 int sequence_id) { | 733 int sequence_id) { |
548 RenderThread::Get()->Send( | 734 RenderThread::Get()->Send( |
549 new ExtensionHostMsg_ShouldCloseAck(extension_id, sequence_id)); | 735 new ExtensionHostMsg_ShouldCloseAck(extension_id, sequence_id)); |
550 } | 736 } |
OLD | NEW |