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