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/browser/extensions/user_script_master.h" | 5 #include "chrome/browser/extensions/user_script_master.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 // Pretend the extension change didn't happen. | 382 // Pretend the extension change didn't happen. |
383 return; | 383 return; |
384 } | 384 } |
385 | 385 |
386 // We've got scripts ready to go. | 386 // We've got scripts ready to go. |
387 shared_memory_ = handle.Pass(); | 387 shared_memory_ = handle.Pass(); |
388 | 388 |
389 for (content::RenderProcessHost::iterator i( | 389 for (content::RenderProcessHost::iterator i( |
390 content::RenderProcessHost::AllHostsIterator()); | 390 content::RenderProcessHost::AllHostsIterator()); |
391 !i.IsAtEnd(); i.Advance()) { | 391 !i.IsAtEnd(); i.Advance()) { |
392 SendUpdate(i.GetCurrentValue(), | 392 SendUpdate(i.GetCurrentValue(), shared_memory_.get()); |
393 shared_memory_.get(), | |
394 changed_extensions_); | |
395 } | 393 } |
396 changed_extensions_.clear(); | |
397 | 394 |
398 content::NotificationService::current()->Notify( | 395 content::NotificationService::current()->Notify( |
399 chrome::NOTIFICATION_USER_SCRIPTS_UPDATED, | 396 chrome::NOTIFICATION_USER_SCRIPTS_UPDATED, |
400 content::Source<Profile>(profile_), | 397 content::Source<Profile>(profile_), |
401 content::Details<base::SharedMemory>(shared_memory_.get())); | 398 content::Details<base::SharedMemory>(shared_memory_.get())); |
402 } | 399 } |
403 } | 400 } |
404 | 401 |
405 ContentVerifier* UserScriptMaster::content_verifier() { | 402 ContentVerifier* UserScriptMaster::content_verifier() { |
406 ExtensionSystem* system = ExtensionSystem::Get(profile_); | 403 ExtensionSystem* system = ExtensionSystem::Get(profile_); |
(...skipping 10 matching lines...) Expand all Loading... |
417 bool incognito_enabled = util::IsIncognitoEnabled(extension->id(), profile_); | 414 bool incognito_enabled = util::IsIncognitoEnabled(extension->id(), profile_); |
418 const UserScriptList& scripts = | 415 const UserScriptList& scripts = |
419 ContentScriptsInfo::GetContentScripts(extension); | 416 ContentScriptsInfo::GetContentScripts(extension); |
420 for (UserScriptList::const_iterator iter = scripts.begin(); | 417 for (UserScriptList::const_iterator iter = scripts.begin(); |
421 iter != scripts.end(); | 418 iter != scripts.end(); |
422 ++iter) { | 419 ++iter) { |
423 user_scripts_.push_back(*iter); | 420 user_scripts_.push_back(*iter); |
424 user_scripts_.back().set_incognito_enabled(incognito_enabled); | 421 user_scripts_.back().set_incognito_enabled(incognito_enabled); |
425 } | 422 } |
426 if (extensions_service_ready_) { | 423 if (extensions_service_ready_) { |
427 changed_extensions_.insert(extension->id()); | |
428 if (script_reloader_.get()) { | 424 if (script_reloader_.get()) { |
429 pending_load_ = true; | 425 pending_load_ = true; |
430 } else { | 426 } else { |
431 StartLoad(); | 427 StartLoad(); |
432 } | 428 } |
433 } | 429 } |
434 } | 430 } |
435 | 431 |
436 void UserScriptMaster::OnExtensionUnloaded( | 432 void UserScriptMaster::OnExtensionUnloaded( |
437 content::BrowserContext* browser_context, | 433 content::BrowserContext* browser_context, |
438 const Extension* extension, | 434 const Extension* extension, |
439 UnloadedExtensionInfo::Reason reason) { | 435 UnloadedExtensionInfo::Reason reason) { |
440 // Remove any content scripts. | 436 // Remove any content scripts. |
441 extensions_info_.erase(extension->id()); | 437 extensions_info_.erase(extension->id()); |
442 UserScriptList new_user_scripts; | 438 UserScriptList new_user_scripts; |
443 for (UserScriptList::iterator iter = user_scripts_.begin(); | 439 for (UserScriptList::iterator iter = user_scripts_.begin(); |
444 iter != user_scripts_.end(); | 440 iter != user_scripts_.end(); |
445 ++iter) { | 441 ++iter) { |
446 if (iter->extension_id() != extension->id()) | 442 if (iter->extension_id() != extension->id()) |
447 new_user_scripts.push_back(*iter); | 443 new_user_scripts.push_back(*iter); |
448 } | 444 } |
449 user_scripts_ = new_user_scripts; | 445 user_scripts_ = new_user_scripts; |
450 changed_extensions_.insert(extension->id()); | |
451 if (script_reloader_.get()) { | 446 if (script_reloader_.get()) { |
452 pending_load_ = true; | 447 pending_load_ = true; |
453 } else { | 448 } else { |
454 StartLoad(); | 449 StartLoad(); |
455 } | 450 } |
456 } | 451 } |
457 | 452 |
458 void UserScriptMaster::Observe(int type, | 453 void UserScriptMaster::Observe(int type, |
459 const content::NotificationSource& source, | 454 const content::NotificationSource& source, |
460 const content::NotificationDetails& details) { | 455 const content::NotificationDetails& details) { |
461 bool should_start_load = false; | 456 bool should_start_load = false; |
462 switch (type) { | 457 switch (type) { |
463 case chrome::NOTIFICATION_EXTENSIONS_READY: | 458 case chrome::NOTIFICATION_EXTENSIONS_READY: |
464 extensions_service_ready_ = true; | 459 extensions_service_ready_ = true; |
465 should_start_load = true; | 460 should_start_load = true; |
466 break; | 461 break; |
467 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { | 462 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { |
468 content::RenderProcessHost* process = | 463 content::RenderProcessHost* process = |
469 content::Source<content::RenderProcessHost>(source).ptr(); | 464 content::Source<content::RenderProcessHost>(source).ptr(); |
470 Profile* profile = Profile::FromBrowserContext( | 465 Profile* profile = Profile::FromBrowserContext( |
471 process->GetBrowserContext()); | 466 process->GetBrowserContext()); |
472 if (!profile_->IsSameProfile(profile)) | 467 if (!profile_->IsSameProfile(profile)) |
473 return; | 468 return; |
474 if (ScriptsReady()) { | 469 if (ScriptsReady()) |
475 SendUpdate(process, | 470 SendUpdate(process, GetSharedMemory()); |
476 GetSharedMemory(), | |
477 std::set<std::string>()); // Include all extensions. | |
478 } | |
479 break; | 471 break; |
480 } | 472 } |
481 default: | 473 default: |
482 DCHECK(false); | 474 DCHECK(false); |
483 } | 475 } |
484 | 476 |
485 if (should_start_load) { | 477 if (should_start_load) { |
486 if (script_reloader_.get()) { | 478 if (script_reloader_.get()) { |
487 pending_load_ = true; | 479 pending_load_ = true; |
488 } else { | 480 } else { |
489 StartLoad(); | 481 StartLoad(); |
490 } | 482 } |
491 } | 483 } |
492 } | 484 } |
493 | 485 |
494 void UserScriptMaster::StartLoad() { | 486 void UserScriptMaster::StartLoad() { |
495 if (!script_reloader_.get()) | 487 if (!script_reloader_.get()) |
496 script_reloader_ = new ScriptReloader(this); | 488 script_reloader_ = new ScriptReloader(this); |
497 | 489 |
498 script_reloader_->StartLoad(user_scripts_, extensions_info_); | 490 script_reloader_->StartLoad(user_scripts_, extensions_info_); |
499 } | 491 } |
500 | 492 |
501 void UserScriptMaster::SendUpdate( | 493 void UserScriptMaster::SendUpdate(content::RenderProcessHost* process, |
502 content::RenderProcessHost* process, | 494 base::SharedMemory* shared_memory) { |
503 base::SharedMemory* shared_memory, | |
504 const std::set<std::string>& changed_extensions) { | |
505 // Don't allow injection of content scripts into <webview>. | 495 // Don't allow injection of content scripts into <webview>. |
506 if (process->IsIsolatedGuest()) | 496 if (process->IsIsolatedGuest()) |
507 return; | 497 return; |
508 | 498 |
509 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); | 499 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); |
510 // Make sure we only send user scripts to processes in our profile. | 500 // Make sure we only send user scripts to processes in our profile. |
511 if (!profile_->IsSameProfile(profile)) | 501 if (!profile_->IsSameProfile(profile)) |
512 return; | 502 return; |
513 | 503 |
514 // If the process is being started asynchronously, early return. We'll end up | 504 // If the process is being started asynchronously, early return. We'll end up |
515 // calling InitUserScripts when it's created which will call this again. | 505 // calling InitUserScripts when it's created which will call this again. |
516 base::ProcessHandle handle = process->GetHandle(); | 506 base::ProcessHandle handle = process->GetHandle(); |
517 if (!handle) | 507 if (!handle) |
518 return; | 508 return; |
519 | 509 |
520 base::SharedMemoryHandle handle_for_process; | 510 base::SharedMemoryHandle handle_for_process; |
521 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) | 511 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) |
522 return; // This can legitimately fail if the renderer asserts at startup. | 512 return; // This can legitimately fail if the renderer asserts at startup. |
523 | 513 |
524 if (base::SharedMemory::IsHandleValid(handle_for_process)) { | 514 if (base::SharedMemory::IsHandleValid(handle_for_process)) |
525 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process, | 515 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process)); |
526 changed_extensions)); | |
527 } | |
528 } | 516 } |
529 | 517 |
530 } // namespace extensions | 518 } // namespace extensions |
OLD | NEW |