| 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 |