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

Side by Side Diff: extensions/renderer/dispatcher.cc

Issue 995283004: Move Extension ScriptContext creation into ScriptContextSet. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Ready Created 5 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/renderer/dispatcher.h" 5 #include "extensions/renderer/dispatcher.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/alias.h" 10 #include "base/debug/alias.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/metrics/histogram_macros.h" 12 #include "base/metrics/histogram_macros.h"
13 #include "base/metrics/user_metrics_action.h" 13 #include "base/metrics/user_metrics_action.h"
14 #include "base/strings/string_piece.h" 14 #include "base/strings/string_piece.h"
15 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "base/values.h" 18 #include "base/values.h"
19 #include "content/grit/content_resources.h" 19 #include "content/grit/content_resources.h"
20 #include "content/public/child/v8_value_converter.h" 20 #include "content/public/child/v8_value_converter.h"
21 #include "content/public/common/content_switches.h" 21 #include "content/public/common/content_switches.h"
22 #include "content/public/common/url_constants.h" 22 #include "content/public/common/url_constants.h"
23 #include "content/public/renderer/render_thread.h" 23 #include "content/public/renderer/render_thread.h"
24 #include "content/public/renderer/render_view.h" 24 #include "content/public/renderer/render_view.h"
25 #include "extensions/common/api/messaging/message.h" 25 #include "extensions/common/api/messaging/message.h"
26 #include "extensions/common/constants.h" 26 #include "extensions/common/constants.h"
27 #include "extensions/common/extension.h"
28 #include "extensions/common/extension_api.h" 27 #include "extensions/common/extension_api.h"
29 #include "extensions/common/extension_messages.h" 28 #include "extensions/common/extension_messages.h"
30 #include "extensions/common/extension_urls.h" 29 #include "extensions/common/extension_urls.h"
31 #include "extensions/common/feature_switch.h" 30 #include "extensions/common/feature_switch.h"
32 #include "extensions/common/features/feature.h" 31 #include "extensions/common/features/feature.h"
33 #include "extensions/common/features/feature_provider.h" 32 #include "extensions/common/features/feature_provider.h"
34 #include "extensions/common/manifest.h" 33 #include "extensions/common/manifest.h"
35 #include "extensions/common/manifest_constants.h" 34 #include "extensions/common/manifest_constants.h"
36 #include "extensions/common/manifest_handlers/background_info.h" 35 #include "extensions/common/manifest_handlers/background_info.h"
37 #include "extensions/common/manifest_handlers/content_capabilities_handler.h" 36 #include "extensions/common/manifest_handlers/content_capabilities_handler.h"
38 #include "extensions/common/manifest_handlers/externally_connectable.h" 37 #include "extensions/common/manifest_handlers/externally_connectable.h"
39 #include "extensions/common/manifest_handlers/options_page_info.h" 38 #include "extensions/common/manifest_handlers/options_page_info.h"
40 #include "extensions/common/manifest_handlers/sandboxed_page_info.h"
41 #include "extensions/common/message_bundle.h" 39 #include "extensions/common/message_bundle.h"
42 #include "extensions/common/permissions/permission_set.h" 40 #include "extensions/common/permissions/permission_set.h"
43 #include "extensions/common/permissions/permissions_data.h" 41 #include "extensions/common/permissions/permissions_data.h"
44 #include "extensions/common/switches.h" 42 #include "extensions/common/switches.h"
45 #include "extensions/common/view_type.h" 43 #include "extensions/common/view_type.h"
46 #include "extensions/renderer/api_activity_logger.h" 44 #include "extensions/renderer/api_activity_logger.h"
47 #include "extensions/renderer/api_definitions_natives.h" 45 #include "extensions/renderer/api_definitions_natives.h"
48 #include "extensions/renderer/app_runtime_custom_bindings.h" 46 #include "extensions/renderer/app_runtime_custom_bindings.h"
49 #include "extensions/renderer/app_window_custom_bindings.h" 47 #include "extensions/renderer/app_window_custom_bindings.h"
50 #include "extensions/renderer/binding_generating_native_handler.h" 48 #include "extensions/renderer/binding_generating_native_handler.h"
51 #include "extensions/renderer/blob_native_handler.h" 49 #include "extensions/renderer/blob_native_handler.h"
52 #include "extensions/renderer/content_watcher.h" 50 #include "extensions/renderer/content_watcher.h"
53 #include "extensions/renderer/context_menus_custom_bindings.h" 51 #include "extensions/renderer/context_menus_custom_bindings.h"
54 #include "extensions/renderer/css_native_handler.h" 52 #include "extensions/renderer/css_native_handler.h"
55 #include "extensions/renderer/dispatcher_delegate.h" 53 #include "extensions/renderer/dispatcher_delegate.h"
56 #include "extensions/renderer/document_custom_bindings.h" 54 #include "extensions/renderer/document_custom_bindings.h"
57 #include "extensions/renderer/dom_activity_logger.h" 55 #include "extensions/renderer/dom_activity_logger.h"
58 #include "extensions/renderer/event_bindings.h" 56 #include "extensions/renderer/event_bindings.h"
59 #include "extensions/renderer/extension_groups.h"
60 #include "extensions/renderer/extension_helper.h" 57 #include "extensions/renderer/extension_helper.h"
61 #include "extensions/renderer/extensions_renderer_client.h" 58 #include "extensions/renderer/extensions_renderer_client.h"
62 #include "extensions/renderer/file_system_natives.h" 59 #include "extensions/renderer/file_system_natives.h"
63 #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h" 60 #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h"
64 #include "extensions/renderer/i18n_custom_bindings.h" 61 #include "extensions/renderer/i18n_custom_bindings.h"
65 #include "extensions/renderer/id_generator_custom_bindings.h" 62 #include "extensions/renderer/id_generator_custom_bindings.h"
66 #include "extensions/renderer/lazy_background_page_native_handler.h" 63 #include "extensions/renderer/lazy_background_page_native_handler.h"
67 #include "extensions/renderer/logging_native_handler.h" 64 #include "extensions/renderer/logging_native_handler.h"
68 #include "extensions/renderer/messaging_bindings.h" 65 #include "extensions/renderer/messaging_bindings.h"
69 #include "extensions/renderer/module_system.h" 66 #include "extensions/renderer/module_system.h"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 command_line.HasSwitch(switches::kExtensionProcess) || 195 command_line.HasSwitch(switches::kExtensionProcess) ||
199 command_line.HasSwitch(::switches::kSingleProcess); 196 command_line.HasSwitch(::switches::kSingleProcess);
200 197
201 if (set_idle_notifications_) { 198 if (set_idle_notifications_) {
202 RenderThread::Get()->SetIdleNotificationDelayInMs( 199 RenderThread::Get()->SetIdleNotificationDelayInMs(
203 kInitialExtensionIdleHandlerDelayMs); 200 kInitialExtensionIdleHandlerDelayMs);
204 } 201 }
205 202
206 RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); 203 RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension());
207 204
205 script_context_set_.reset(
206 new ScriptContextSet(&extensions_, &active_extension_ids_));
208 user_script_set_manager_.reset(new UserScriptSetManager(&extensions_)); 207 user_script_set_manager_.reset(new UserScriptSetManager(&extensions_));
209 script_injection_manager_.reset( 208 script_injection_manager_.reset(
210 new ScriptInjectionManager(&extensions_, user_script_set_manager_.get())); 209 new ScriptInjectionManager(&extensions_, user_script_set_manager_.get()));
211 user_script_set_manager_observer_.Add(user_script_set_manager_.get()); 210 user_script_set_manager_observer_.Add(user_script_set_manager_.get());
212 request_sender_.reset(new RequestSender(this)); 211 request_sender_.reset(new RequestSender(this));
213 PopulateSourceMap(); 212 PopulateSourceMap();
214 } 213 }
215 214
216 Dispatcher::~Dispatcher() { 215 Dispatcher::~Dispatcher() {
217 } 216 }
218 217
219 void Dispatcher::OnRenderViewCreated(content::RenderView* render_view) { 218 void Dispatcher::OnRenderViewCreated(content::RenderView* render_view) {
220 script_injection_manager_->OnRenderViewCreated(render_view); 219 script_injection_manager_->OnRenderViewCreated(render_view);
221 } 220 }
222 221
223 bool Dispatcher::IsExtensionActive(const std::string& extension_id) const { 222 bool Dispatcher::IsExtensionActive(const std::string& extension_id) const {
224 bool is_active = 223 bool is_active =
225 active_extension_ids_.find(extension_id) != active_extension_ids_.end(); 224 active_extension_ids_.find(extension_id) != active_extension_ids_.end();
226 if (is_active) 225 if (is_active)
227 CHECK(extensions_.Contains(extension_id)); 226 CHECK(extensions_.Contains(extension_id));
228 return is_active; 227 return is_active;
229 } 228 }
230 229
231 const Extension* Dispatcher::GetExtensionFromFrameAndWorld(
232 const blink::WebFrame* frame,
233 int world_id,
234 bool use_effective_url) {
235 std::string extension_id;
236 if (world_id != 0) {
237 // Isolated worlds (content script).
238 extension_id = ScriptInjection::GetHostIdForIsolatedWorld(world_id);
239 } else if (!frame->document().securityOrigin().isUnique()) {
240 // TODO(kalman): Delete the above check.
241
242 // Extension pages (chrome-extension:// URLs).
243 GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame);
244 frame_url = ScriptContext::GetEffectiveDocumentURL(
245 frame, frame_url, use_effective_url);
246 extension_id = extensions_.GetExtensionOrAppIDByURL(frame_url);
247 }
248
249 const Extension* extension = extensions_.GetByID(extension_id);
250 if (!extension && !extension_id.empty()) {
251 // There are conditions where despite a context being associated with an
252 // extension, no extension actually gets found. Ignore "invalid" because
253 // CSP blocks extension page loading by switching the extension ID to
254 // "invalid". This isn't interesting.
255 if (extension_id != "invalid") {
256 LOG(ERROR) << "Extension \"" << extension_id << "\" not found";
257 RenderThread::Get()->RecordAction(
258 UserMetricsAction("ExtensionNotFound_ED"));
259 }
260 }
261 return extension;
262 }
263
264 void Dispatcher::DidCreateScriptContext( 230 void Dispatcher::DidCreateScriptContext(
265 blink::WebLocalFrame* frame, 231 blink::WebLocalFrame* frame,
266 const v8::Handle<v8::Context>& v8_context, 232 const v8::Handle<v8::Context>& v8_context,
267 int extension_group, 233 int extension_group,
268 int world_id) { 234 int world_id) {
269 const base::TimeTicks start_time = base::TimeTicks::Now(); 235 const base::TimeTicks start_time = base::TimeTicks::Now();
270 236
271 const Extension* extension = 237 ScriptContext* context = script_context_set_->Register(
272 GetExtensionFromFrameAndWorld(frame, world_id, false); 238 frame, v8_context, extension_group, world_id);
273 const Extension* effective_extension =
274 GetExtensionFromFrameAndWorld(frame, world_id, true);
275
276 GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame);
277 Feature::Context context_type =
278 ClassifyJavaScriptContext(extension,
279 extension_group,
280 frame_url,
281 frame->document().securityOrigin());
282 Feature::Context effective_context_type = ClassifyJavaScriptContext(
283 effective_extension,
284 extension_group,
285 ScriptContext::GetEffectiveDocumentURL(frame, frame_url, true),
286 frame->document().securityOrigin());
287
288 ScriptContext* context =
289 new ScriptContext(v8_context, frame, extension, context_type,
290 effective_extension, effective_context_type);
291 script_context_set_.Add(context);
292 239
293 // Initialize origin permissions for content scripts, which can't be 240 // Initialize origin permissions for content scripts, which can't be
294 // initialized in |OnActivateExtension|. 241 // initialized in |OnActivateExtension|.
295 if (context_type == Feature::CONTENT_SCRIPT_CONTEXT) 242 if (context->context_type() == Feature::CONTENT_SCRIPT_CONTEXT)
296 InitOriginPermissions(extension); 243 InitOriginPermissions(context->extension());
297 244
298 { 245 {
299 scoped_ptr<ModuleSystem> module_system( 246 scoped_ptr<ModuleSystem> module_system(
300 new ModuleSystem(context, &source_map_)); 247 new ModuleSystem(context, &source_map_));
301 context->set_module_system(module_system.Pass()); 248 context->set_module_system(module_system.Pass());
302 } 249 }
303 ModuleSystem* module_system = context->module_system(); 250 ModuleSystem* module_system = context->module_system();
304 251
305 // Enable natives in startup. 252 // Enable natives in startup.
306 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); 253 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system);
(...skipping 12 matching lines...) Expand all
319 UpdateBindingsForContext(context); 266 UpdateBindingsForContext(context);
320 267
321 bool is_within_platform_app = IsWithinPlatformApp(); 268 bool is_within_platform_app = IsWithinPlatformApp();
322 // Inject custom JS into the platform app context. 269 // Inject custom JS into the platform app context.
323 if (is_within_platform_app) { 270 if (is_within_platform_app) {
324 module_system->Require("platformApp"); 271 module_system->Require("platformApp");
325 } 272 }
326 273
327 if (context->GetAvailability("appViewEmbedderInternal").is_available()) { 274 if (context->GetAvailability("appViewEmbedderInternal").is_available()) {
328 module_system->Require("appView"); 275 module_system->Require("appView");
329 } else if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { 276 } else if (context->context_type() == Feature::BLESSED_EXTENSION_CONTEXT) {
330 module_system->Require("appViewDeny"); 277 module_system->Require("appViewDeny");
331 } 278 }
332 279
333 if (extensions::FeatureSwitch::surface_worker()->IsEnabled() && 280 if (extensions::FeatureSwitch::surface_worker()->IsEnabled() &&
334 context->GetAvailability("surfaceWorkerInternal").is_available()) { 281 context->GetAvailability("surfaceWorkerInternal").is_available()) {
335 module_system->Require("surfaceWorker"); 282 module_system->Require("surfaceWorker");
336 } 283 }
337 284
338 if (context->GetAvailability("extensionViewInternal").is_available()) { 285 if (context->GetAvailability("extensionViewInternal").is_available()) {
339 module_system->Require("extensionView"); 286 module_system->Require("extensionView");
340 module_system->Require("extensionViewApiMethods"); 287 module_system->Require("extensionViewApiMethods");
341 module_system->Require("extensionViewAttributes"); 288 module_system->Require("extensionViewAttributes");
342 } 289 }
343 290
344 // Note: setting up the WebView class here, not the chrome.webview API. 291 // Note: setting up the WebView class here, not the chrome.webview API.
345 // The API will be automatically set up when first used. 292 // The API will be automatically set up when first used.
346 if (context->GetAvailability("webViewInternal").is_available()) { 293 if (context->GetAvailability("webViewInternal").is_available()) {
347 module_system->Require("webView"); 294 module_system->Require("webView");
348 module_system->Require("webViewApiMethods"); 295 module_system->Require("webViewApiMethods");
349 module_system->Require("webViewAttributes"); 296 module_system->Require("webViewAttributes");
350 if (context->GetAvailability("webViewExperimentalInternal") 297 if (context->GetAvailability("webViewExperimentalInternal")
351 .is_available()) { 298 .is_available()) {
352 module_system->Require("webViewExperimental"); 299 module_system->Require("webViewExperimental");
353 } 300 }
354 } else if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { 301 } else if (context->context_type() == Feature::BLESSED_EXTENSION_CONTEXT) {
355 module_system->Require("webViewDeny"); 302 module_system->Require("webViewDeny");
356 } 303 }
357 304
358 delegate_->RequireAdditionalModules(context, is_within_platform_app); 305 delegate_->RequireAdditionalModules(context, is_within_platform_app);
359 306
360 const base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; 307 const base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
361 switch (context_type) { 308 switch (context->context_type()) {
362 case Feature::UNSPECIFIED_CONTEXT: 309 case Feature::UNSPECIFIED_CONTEXT:
363 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Unspecified", 310 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Unspecified",
364 elapsed); 311 elapsed);
365 break; 312 break;
366 case Feature::BLESSED_EXTENSION_CONTEXT: 313 case Feature::BLESSED_EXTENSION_CONTEXT:
367 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Blessed", elapsed); 314 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Blessed", elapsed);
368 break; 315 break;
369 case Feature::UNBLESSED_EXTENSION_CONTEXT: 316 case Feature::UNBLESSED_EXTENSION_CONTEXT:
370 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Unblessed", 317 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Unblessed",
371 elapsed); 318 elapsed);
372 break; 319 break;
373 case Feature::CONTENT_SCRIPT_CONTEXT: 320 case Feature::CONTENT_SCRIPT_CONTEXT:
374 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_ContentScript", 321 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_ContentScript",
375 elapsed); 322 elapsed);
376 break; 323 break;
377 case Feature::WEB_PAGE_CONTEXT: 324 case Feature::WEB_PAGE_CONTEXT:
378 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_WebPage", elapsed); 325 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_WebPage", elapsed);
379 break; 326 break;
380 case Feature::BLESSED_WEB_PAGE_CONTEXT: 327 case Feature::BLESSED_WEB_PAGE_CONTEXT:
381 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_BlessedWebPage", 328 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_BlessedWebPage",
382 elapsed); 329 elapsed);
383 break; 330 break;
384 case Feature::WEBUI_CONTEXT: 331 case Feature::WEBUI_CONTEXT:
385 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_WebUI", elapsed); 332 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_WebUI", elapsed);
386 break; 333 break;
387 } 334 }
388 335
389 VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); 336 VLOG(1) << "Num tracked contexts: " << script_context_set_->size();
390 } 337 }
391 338
392 void Dispatcher::WillReleaseScriptContext( 339 void Dispatcher::WillReleaseScriptContext(
393 blink::WebLocalFrame* frame, 340 blink::WebLocalFrame* frame,
394 const v8::Handle<v8::Context>& v8_context, 341 const v8::Handle<v8::Context>& v8_context,
395 int world_id) { 342 int world_id) {
396 ScriptContext* context = script_context_set_.GetByV8Context(v8_context); 343 ScriptContext* context = script_context_set_->GetByV8Context(v8_context);
397 if (!context) 344 if (!context)
398 return; 345 return;
399 346
400 context->DispatchOnUnloadEvent(); 347 context->DispatchOnUnloadEvent();
401 // TODO(kalman): add an invalidation observer interface to ScriptContext. 348 // TODO(kalman): add an invalidation observer interface to ScriptContext.
402 request_sender_->InvalidateSource(context); 349 request_sender_->InvalidateSource(context);
403 350
404 script_context_set_.Remove(context); 351 script_context_set_->Remove(context);
405 VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); 352 VLOG(1) << "Num tracked contexts: " << script_context_set_->size();
406 } 353 }
407 354
408 void Dispatcher::DidCreateDocumentElement(blink::WebFrame* frame) { 355 void Dispatcher::DidCreateDocumentElement(blink::WebFrame* frame) {
409 // Note: use GetEffectiveDocumentURL not just frame->document()->url() 356 // Note: use GetEffectiveDocumentURL not just frame->document()->url()
410 // so that this also injects the stylesheet on about:blank frames that 357 // so that this also injects the stylesheet on about:blank frames that
411 // are hosted in the extension process. 358 // are hosted in the extension process.
412 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL( 359 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL(
413 frame, frame->document().url(), true /* match_about_blank */); 360 frame, frame->document().url(), true /* match_about_blank */);
414 361
415 const Extension* extension = 362 const Extension* extension =
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 const std::string& function_name, 413 const std::string& function_name,
467 ScriptContext* context) const { 414 ScriptContext* context) const {
468 if (!context) { 415 if (!context) {
469 DLOG(ERROR) << "Not in a v8::Context"; 416 DLOG(ERROR) << "Not in a v8::Context";
470 return false; 417 return false;
471 } 418 }
472 419
473 // Theoretically we could end up with bindings being injected into sandboxed 420 // Theoretically we could end up with bindings being injected into sandboxed
474 // frames, for example content scripts. Don't let them execute API functions. 421 // frames, for example content scripts. Don't let them execute API functions.
475 blink::WebFrame* frame = context->web_frame(); 422 blink::WebFrame* frame = context->web_frame();
476 if (IsSandboxedPage(ScriptContext::GetDataSourceURLForFrame(frame))) { 423 if (ScriptContext::IsSandboxedPage(
424 extensions_, ScriptContext::GetDataSourceURLForFrame(frame))) {
477 static const char kMessage[] = 425 static const char kMessage[] =
478 "%s cannot be used within a sandboxed frame."; 426 "%s cannot be used within a sandboxed frame.";
479 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); 427 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
480 context->isolate()->ThrowException(v8::Exception::Error( 428 context->isolate()->ThrowException(v8::Exception::Error(
481 v8::String::NewFromUtf8(context->isolate(), error_msg.c_str()))); 429 v8::String::NewFromUtf8(context->isolate(), error_msg.c_str())));
482 return false; 430 return false;
483 } 431 }
484 432
485 Feature::Availability availability = context->GetAvailability(function_name); 433 Feature::Availability availability = context->GetAvailability(function_name);
486 if (!availability.is_available()) { 434 if (!availability.is_available()) {
487 context->isolate()->ThrowException( 435 context->isolate()->ThrowException(
488 v8::Exception::Error(v8::String::NewFromUtf8( 436 v8::Exception::Error(v8::String::NewFromUtf8(
489 context->isolate(), availability.message().c_str()))); 437 context->isolate(), availability.message().c_str())));
490 } 438 }
491 439
492 return availability.is_available(); 440 return availability.is_available();
493 } 441 }
494 442
495 void Dispatcher::DispatchEvent(const std::string& extension_id, 443 void Dispatcher::DispatchEvent(const std::string& extension_id,
496 const std::string& event_name) const { 444 const std::string& event_name) const {
497 base::ListValue args; 445 base::ListValue args;
498 args.Set(0, new base::StringValue(event_name)); 446 args.Set(0, new base::StringValue(event_name));
499 args.Set(1, new base::ListValue()); 447 args.Set(1, new base::ListValue());
500 448
501 // Needed for Windows compilation, since kEventBindings is declared extern. 449 // Needed for Windows compilation, since kEventBindings is declared extern.
502 const char* local_event_bindings = kEventBindings; 450 const char* local_event_bindings = kEventBindings;
503 script_context_set_.ForEach(extension_id, 451 script_context_set_->ForEach(
504 base::Bind(&CallModuleMethod, 452 extension_id, base::Bind(&CallModuleMethod, local_event_bindings,
505 local_event_bindings, 453 kEventDispatchFunction, &args));
506 kEventDispatchFunction,
507 &args));
508 } 454 }
509 455
510 void Dispatcher::InvokeModuleSystemMethod(content::RenderView* render_view, 456 void Dispatcher::InvokeModuleSystemMethod(content::RenderView* render_view,
511 const std::string& extension_id, 457 const std::string& extension_id,
512 const std::string& module_name, 458 const std::string& module_name,
513 const std::string& function_name, 459 const std::string& function_name,
514 const base::ListValue& args, 460 const base::ListValue& args,
515 bool user_gesture) { 461 bool user_gesture) {
516 scoped_ptr<WebScopedUserGesture> web_user_gesture; 462 scoped_ptr<WebScopedUserGesture> web_user_gesture;
517 if (user_gesture) 463 if (user_gesture)
518 web_user_gesture.reset(new WebScopedUserGesture); 464 web_user_gesture.reset(new WebScopedUserGesture);
519 465
520 script_context_set_.ForEach( 466 script_context_set_->ForEach(
521 extension_id, 467 extension_id, render_view,
522 render_view,
523 base::Bind(&CallModuleMethod, module_name, function_name, &args)); 468 base::Bind(&CallModuleMethod, module_name, function_name, &args));
524 469
525 // Reset the idle handler each time there's any activity like event or message 470 // Reset the idle handler each time there's any activity like event or message
526 // dispatch, for which Invoke is the chokepoint. 471 // dispatch, for which Invoke is the chokepoint.
527 if (set_idle_notifications_) { 472 if (set_idle_notifications_) {
528 RenderThread::Get()->ScheduleIdleHandler( 473 RenderThread::Get()->ScheduleIdleHandler(
529 kInitialExtensionIdleHandlerDelayMs); 474 kInitialExtensionIdleHandlerDelayMs);
530 } 475 }
531 476
532 // Tell the browser process when an event has been dispatched with a lazy 477 // Tell the browser process when an event has been dispatched with a lazy
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 865
921 void Dispatcher::OnDeliverMessage(int target_port_id, const Message& message) { 866 void Dispatcher::OnDeliverMessage(int target_port_id, const Message& message) {
922 scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id; 867 scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id;
923 std::map<int, int>::const_iterator it = 868 std::map<int, int>::const_iterator it =
924 port_to_tab_id_map_.find(target_port_id); 869 port_to_tab_id_map_.find(target_port_id);
925 if (it != port_to_tab_id_map_.end()) { 870 if (it != port_to_tab_id_map_.end()) {
926 scoped_tab_id.reset( 871 scoped_tab_id.reset(
927 new RequestSender::ScopedTabID(request_sender(), it->second)); 872 new RequestSender::ScopedTabID(request_sender(), it->second));
928 } 873 }
929 874
930 MessagingBindings::DeliverMessage(script_context_set_, 875 MessagingBindings::DeliverMessage(*script_context_set_, target_port_id,
931 target_port_id,
932 message, 876 message,
933 NULL); // All render frames. 877 NULL); // All render frames.
934 } 878 }
935 879
936 void Dispatcher::OnDispatchOnConnect( 880 void Dispatcher::OnDispatchOnConnect(
937 int target_port_id, 881 int target_port_id,
938 const std::string& channel_name, 882 const std::string& channel_name,
939 const ExtensionMsg_TabConnectionInfo& source, 883 const ExtensionMsg_TabConnectionInfo& source,
940 const ExtensionMsg_ExternalConnectionInfo& info, 884 const ExtensionMsg_ExternalConnectionInfo& info,
941 const std::string& tls_channel_id) { 885 const std::string& tls_channel_id) {
942 DCHECK(!ContainsKey(port_to_tab_id_map_, target_port_id)); 886 DCHECK(!ContainsKey(port_to_tab_id_map_, target_port_id));
943 DCHECK_EQ(1, target_port_id % 2); // target renderer ports have odd IDs. 887 DCHECK_EQ(1, target_port_id % 2); // target renderer ports have odd IDs.
944 int sender_tab_id = -1; 888 int sender_tab_id = -1;
945 source.tab.GetInteger("id", &sender_tab_id); 889 source.tab.GetInteger("id", &sender_tab_id);
946 port_to_tab_id_map_[target_port_id] = sender_tab_id; 890 port_to_tab_id_map_[target_port_id] = sender_tab_id;
947 891
948 MessagingBindings::DispatchOnConnect(script_context_set_, 892 MessagingBindings::DispatchOnConnect(*script_context_set_, target_port_id,
949 target_port_id, 893 channel_name, source, info,
950 channel_name,
951 source,
952 info,
953 tls_channel_id, 894 tls_channel_id,
954 NULL); // All render frames. 895 NULL); // All render frames.
955 } 896 }
956 897
957 void Dispatcher::OnDispatchOnDisconnect(int port_id, 898 void Dispatcher::OnDispatchOnDisconnect(int port_id,
958 const std::string& error_message) { 899 const std::string& error_message) {
959 MessagingBindings::DispatchOnDisconnect(script_context_set_, 900 MessagingBindings::DispatchOnDisconnect(*script_context_set_, port_id,
960 port_id,
961 error_message, 901 error_message,
962 NULL); // All render frames. 902 NULL); // All render frames.
963 } 903 }
964 904
965 void Dispatcher::OnLoaded( 905 void Dispatcher::OnLoaded(
966 const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) { 906 const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) {
967 std::vector<ExtensionMsg_Loaded_Params>::const_iterator i; 907 std::vector<ExtensionMsg_Loaded_Params>::const_iterator i;
968 for (i = loaded_extensions.begin(); i != loaded_extensions.end(); ++i) { 908 for (i = loaded_extensions.begin(); i != loaded_extensions.end(); ++i) {
969 std::string error; 909 std::string error;
970 scoped_refptr<const Extension> extension = i->ConvertToExtension(&error); 910 scoped_refptr<const Extension> extension = i->ConvertToExtension(&error);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 980
1041 script_injection_manager_->OnExtensionUnloaded(id); 981 script_injection_manager_->OnExtensionUnloaded(id);
1042 982
1043 // If the extension is later reloaded with a different set of permissions, 983 // If the extension is later reloaded with a different set of permissions,
1044 // we'd like it to get a new isolated world ID, so that it can pick up the 984 // we'd like it to get a new isolated world ID, so that it can pick up the
1045 // changed origin whitelist. 985 // changed origin whitelist.
1046 ScriptInjection::RemoveIsolatedWorld(id); 986 ScriptInjection::RemoveIsolatedWorld(id);
1047 987
1048 // Invalidate all of the contexts that were removed. 988 // Invalidate all of the contexts that were removed.
1049 // TODO(kalman): add an invalidation observer interface to ScriptContext. 989 // TODO(kalman): add an invalidation observer interface to ScriptContext.
1050 ScriptContextSet::ContextSet removed_contexts = 990 std::set<ScriptContext*> removed_contexts =
1051 script_context_set_.OnExtensionUnloaded(id); 991 script_context_set_->OnExtensionUnloaded(id);
1052 for (ScriptContextSet::ContextSet::iterator it = removed_contexts.begin(); 992 for (ScriptContext* context : removed_contexts) {
1053 it != removed_contexts.end(); 993 request_sender_->InvalidateSource(context);
1054 ++it) {
1055 request_sender_->InvalidateSource(*it);
1056 } 994 }
1057 995
1058 // Update the available bindings for the remaining contexts. These may have 996 // Update the available bindings for the remaining contexts. These may have
1059 // changed if an externally_connectable extension is unloaded and a webpage 997 // changed if an externally_connectable extension is unloaded and a webpage
1060 // is no longer accessible. 998 // is no longer accessible.
1061 UpdateBindings(""); 999 UpdateBindings("");
1062 1000
1063 // Invalidates the messages map for the extension in case the extension is 1001 // Invalidates the messages map for the extension in case the extension is
1064 // reloaded with a new messages map. 1002 // reloaded with a new messages map.
1065 EraseL10nMessagesMap(id); 1003 EraseL10nMessagesMap(id);
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); 1349 for (std::set<std::string>::iterator iter = active_extension_ids_.begin();
1412 iter != active_extension_ids_.end(); 1350 iter != active_extension_ids_.end();
1413 ++iter) { 1351 ++iter) {
1414 const Extension* extension = extensions_.GetByID(*iter); 1352 const Extension* extension = extensions_.GetByID(*iter);
1415 if (extension && extension->is_platform_app()) 1353 if (extension && extension->is_platform_app())
1416 return true; 1354 return true;
1417 } 1355 }
1418 return false; 1356 return false;
1419 } 1357 }
1420 1358
1421 // TODO(kalman): This is checking for the wrong thing, it should be checking if
1422 // the frame's security origin is unique. The extension sandbox directive is
1423 // checked for in extensions/common/manifest_handlers/csp_info.cc.
1424 bool Dispatcher::IsSandboxedPage(const GURL& url) const {
1425 if (url.SchemeIs(kExtensionScheme)) {
1426 const Extension* extension = extensions_.GetByID(url.host());
1427 if (extension) {
1428 return SandboxedPageInfo::IsSandboxedPage(extension, url.path());
1429 }
1430 }
1431 return false;
1432 }
1433
1434 Feature::Context Dispatcher::ClassifyJavaScriptContext(
1435 const Extension* extension,
1436 int extension_group,
1437 const GURL& url,
1438 const blink::WebSecurityOrigin& origin) {
1439 // WARNING: This logic must match ProcessMap::GetContextType, as much as
1440 // possible.
1441
1442 DCHECK_GE(extension_group, 0);
1443 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
1444 return extension ? // TODO(kalman): when does this happen?
1445 Feature::CONTENT_SCRIPT_CONTEXT
1446 : Feature::UNSPECIFIED_CONTEXT;
1447 }
1448
1449 // We have an explicit check for sandboxed pages before checking whether the
1450 // extension is active in this process because:
1451 // 1. Sandboxed pages run in the same process as regular extension pages, so
1452 // the extension is considered active.
1453 // 2. ScriptContext creation (which triggers bindings injection) happens
1454 // before the SecurityContext is updated with the sandbox flags (after
1455 // reading the CSP header), so the caller can't check if the context's
1456 // security origin is unique yet.
1457 if (IsSandboxedPage(url))
1458 return Feature::WEB_PAGE_CONTEXT;
1459
1460 if (extension && IsExtensionActive(extension->id())) {
1461 // |extension| is active in this process, but it could be either a true
1462 // extension process or within the extent of a hosted app. In the latter
1463 // case this would usually be considered a (blessed) web page context,
1464 // unless the extension in question is a component extension, in which case
1465 // we cheat and call it blessed.
1466 return (extension->is_hosted_app() &&
1467 extension->location() != Manifest::COMPONENT)
1468 ? Feature::BLESSED_WEB_PAGE_CONTEXT
1469 : Feature::BLESSED_EXTENSION_CONTEXT;
1470 }
1471
1472 // TODO(kalman): This isUnique() check is wrong, it should be performed as
1473 // part of IsSandboxedPage().
1474 if (!origin.isUnique() && extensions_.ExtensionBindingsAllowed(url)) {
1475 if (!extension) // TODO(kalman): when does this happen?
1476 return Feature::UNSPECIFIED_CONTEXT;
1477 return extension->is_hosted_app() ? Feature::BLESSED_WEB_PAGE_CONTEXT
1478 : Feature::UNBLESSED_EXTENSION_CONTEXT;
1479 }
1480
1481 if (!url.is_valid())
1482 return Feature::UNSPECIFIED_CONTEXT;
1483
1484 if (url.SchemeIs(content::kChromeUIScheme))
1485 return Feature::WEBUI_CONTEXT;
1486
1487 return Feature::WEB_PAGE_CONTEXT;
1488 }
1489
1490 v8::Handle<v8::Object> Dispatcher::GetOrCreateObject( 1359 v8::Handle<v8::Object> Dispatcher::GetOrCreateObject(
1491 const v8::Handle<v8::Object>& object, 1360 const v8::Handle<v8::Object>& object,
1492 const std::string& field, 1361 const std::string& field,
1493 v8::Isolate* isolate) { 1362 v8::Isolate* isolate) {
1494 v8::Handle<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str()); 1363 v8::Handle<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str());
1495 // If the object has a callback property, it is assumed it is an unavailable 1364 // If the object has a callback property, it is assumed it is an unavailable
1496 // API, so it is safe to delete. This is checked before GetOrCreateObject is 1365 // API, so it is safe to delete. This is checked before GetOrCreateObject is
1497 // called. 1366 // called.
1498 if (object->HasRealNamedCallbackProperty(key)) { 1367 if (object->HasRealNamedCallbackProperty(key)) {
1499 object->Delete(key); 1368 object->Delete(key);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1553 return v8::Handle<v8::Object>(); 1422 return v8::Handle<v8::Object>();
1554 1423
1555 if (bind_name) 1424 if (bind_name)
1556 *bind_name = split.back(); 1425 *bind_name = split.back();
1557 1426
1558 return bind_object.IsEmpty() ? AsObjectOrEmpty(GetOrCreateChrome(context)) 1427 return bind_object.IsEmpty() ? AsObjectOrEmpty(GetOrCreateChrome(context))
1559 : bind_object; 1428 : bind_object;
1560 } 1429 }
1561 1430
1562 } // namespace extensions 1431 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698