Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 : frontend_(NULL), | 232 : frontend_(NULL), |
| 233 install_directory_(install_directory), | 233 install_directory_(install_directory), |
| 234 alert_on_error_(false) { | 234 alert_on_error_(false) { |
| 235 } | 235 } |
| 236 | 236 |
| 237 ExtensionServiceBackend::~ExtensionServiceBackend() { | 237 ExtensionServiceBackend::~ExtensionServiceBackend() { |
| 238 } | 238 } |
| 239 | 239 |
| 240 void ExtensionServiceBackend::LoadSingleExtension( | 240 void ExtensionServiceBackend::LoadSingleExtension( |
| 241 const FilePath& path_in, scoped_refptr<ExtensionService> frontend) { | 241 const FilePath& path_in, scoped_refptr<ExtensionService> frontend) { |
| 242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 242 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 243 | 243 |
| 244 frontend_ = frontend; | 244 frontend_ = frontend; |
| 245 | 245 |
| 246 // Explicit UI loads are always noisy. | 246 // Explicit UI loads are always noisy. |
| 247 alert_on_error_ = true; | 247 alert_on_error_ = true; |
| 248 | 248 |
| 249 FilePath extension_path = path_in; | 249 FilePath extension_path = path_in; |
| 250 file_util::AbsolutePath(&extension_path); | 250 file_util::AbsolutePath(&extension_path); |
| 251 | 251 |
| 252 std::string error; | 252 std::string error; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 265 // prefs. | 265 // prefs. |
| 266 BrowserThread::PostTask( | 266 BrowserThread::PostTask( |
| 267 BrowserThread::UI, FROM_HERE, | 267 BrowserThread::UI, FROM_HERE, |
| 268 NewRunnableMethod(frontend_, | 268 NewRunnableMethod(frontend_, |
| 269 &ExtensionService::OnExtensionInstalled, | 269 &ExtensionService::OnExtensionInstalled, |
| 270 extension)); | 270 extension)); |
| 271 } | 271 } |
| 272 | 272 |
| 273 void ExtensionServiceBackend::ReportExtensionLoadError( | 273 void ExtensionServiceBackend::ReportExtensionLoadError( |
| 274 const FilePath& extension_path, const std::string &error) { | 274 const FilePath& extension_path, const std::string &error) { |
| 275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 275 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 276 BrowserThread::PostTask( | 276 BrowserThread::PostTask( |
| 277 BrowserThread::UI, FROM_HERE, | 277 BrowserThread::UI, FROM_HERE, |
| 278 NewRunnableMethod( | 278 NewRunnableMethod( |
| 279 frontend_, | 279 frontend_, |
| 280 &ExtensionService::ReportExtensionLoadError, extension_path, | 280 &ExtensionService::ReportExtensionLoadError, extension_path, |
| 281 error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_)); | 281 error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_)); |
| 282 } | 282 } |
| 283 | 283 |
| 284 void ExtensionService::CheckExternalUninstall(const std::string& id) { | 284 void ExtensionService::CheckExternalUninstall(const std::string& id) { |
| 285 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 285 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 286 | 286 |
| 287 // Check if the providers know about this extension. | 287 // Check if the providers know about this extension. |
| 288 ProviderCollection::const_iterator i; | 288 ProviderCollection::const_iterator i; |
| 289 for (i = external_extension_providers_.begin(); | 289 for (i = external_extension_providers_.begin(); |
| 290 i != external_extension_providers_.end(); ++i) { | 290 i != external_extension_providers_.end(); ++i) { |
| 291 DCHECK(i->get()->IsReady()); | 291 DCHECK(i->get()->IsReady()); |
| 292 if (i->get()->HasExtension(id)) | 292 if (i->get()->HasExtension(id)) |
| 293 return; // Yup, known extension, don't uninstall. | 293 return; // Yup, known extension, don't uninstall. |
| 294 } | 294 } |
| 295 | 295 |
| 296 // This is an external extension that we don't have registered. Uninstall. | 296 // This is an external extension that we don't have registered. Uninstall. |
| 297 UninstallExtension(id, true); | 297 UninstallExtension(id, true); |
| 298 } | 298 } |
| 299 | 299 |
| 300 void ExtensionService::ClearProvidersForTesting() { | 300 void ExtensionService::ClearProvidersForTesting() { |
| 301 external_extension_providers_.clear(); | 301 external_extension_providers_.clear(); |
| 302 } | 302 } |
| 303 | 303 |
| 304 void ExtensionService::AddProviderForTesting( | 304 void ExtensionService::AddProviderForTesting( |
| 305 ExternalExtensionProviderInterface* test_provider) { | 305 ExternalExtensionProviderInterface* test_provider) { |
| 306 DCHECK(test_provider); | 306 CHECK(test_provider); |
| 307 external_extension_providers_.push_back( | 307 external_extension_providers_.push_back( |
| 308 linked_ptr<ExternalExtensionProviderInterface>(test_provider)); | 308 linked_ptr<ExternalExtensionProviderInterface>(test_provider)); |
| 309 } | 309 } |
| 310 | 310 |
| 311 void ExtensionService::OnExternalExtensionUpdateUrlFound( | 311 void ExtensionService::OnExternalExtensionUpdateUrlFound( |
| 312 const std::string& id, | 312 const std::string& id, |
| 313 const GURL& update_url, | 313 const GURL& update_url, |
| 314 Extension::Location location) { | 314 Extension::Location location) { |
| 315 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 315 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 316 CHECK(Extension::IdIsValid(id)); | 316 CHECK(Extension::IdIsValid(id)); |
| 317 | 317 |
| 318 if (GetExtensionById(id, true)) { | 318 if (GetExtensionById(id, true)) { |
| 319 // Already installed. Do not change the update URL that the extension set. | 319 // Already installed. Do not change the update URL that the extension set. |
| 320 return; | 320 return; |
| 321 } | 321 } |
| 322 AddPendingExtensionFromExternalUpdateUrl(id, update_url, location); | 322 AddPendingExtensionFromExternalUpdateUrl(id, update_url, location); |
| 323 external_extension_added_ |= true; | 323 external_extension_url_added_ |= true; |
| 324 } | 324 } |
| 325 | 325 |
| 326 bool ExtensionService::IsDownloadFromGallery(const GURL& download_url, | 326 bool ExtensionService::IsDownloadFromGallery(const GURL& download_url, |
| 327 const GURL& referrer_url) { | 327 const GURL& referrer_url) { |
| 328 // Special-case the themes mini-gallery. | 328 // Special-case the themes mini-gallery. |
| 329 // TODO(erikkay) When that gallery goes away, remove this code. | 329 // TODO(erikkay) When that gallery goes away, remove this code. |
| 330 if (IsDownloadFromMiniGallery(download_url) && | 330 if (IsDownloadFromMiniGallery(download_url) && |
| 331 StartsWithASCII(referrer_url.spec(), | 331 StartsWithASCII(referrer_url.spec(), |
| 332 extension_urls::kMiniGalleryBrowsePrefix, false)) { | 332 extension_urls::kMiniGalleryBrowsePrefix, false)) { |
| 333 return true; | 333 return true; |
| 334 } | 334 } |
| 335 | 335 |
| 336 const Extension* download_extension = GetExtensionByWebExtent(download_url); | 336 const Extension* download_extension = GetExtensionByWebExtent(download_url); |
| 337 const Extension* referrer_extension = GetExtensionByWebExtent(referrer_url); | 337 const Extension* referrer_extension = GetExtensionByWebExtent(referrer_url); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 | 385 |
| 386 // Check for packaged app. | 386 // Check for packaged app. |
| 387 const Extension* extension = GetExtensionByURL(url); | 387 const Extension* extension = GetExtensionByURL(url); |
| 388 return extension != NULL && extension->is_app(); | 388 return extension != NULL && extension->is_app(); |
| 389 } | 389 } |
| 390 | 390 |
| 391 // static | 391 // static |
| 392 bool ExtensionService::UninstallExtensionHelper( | 392 bool ExtensionService::UninstallExtensionHelper( |
| 393 ExtensionService* extensions_service, | 393 ExtensionService* extensions_service, |
| 394 const std::string& extension_id) { | 394 const std::string& extension_id) { |
| 395 DCHECK(extensions_service); | 395 CHECK(extensions_service); |
|
Erik does not do reviews
2011/01/21 17:05:25
you can remove this since the next line crashes th
Sam Kerner (Chrome)
2011/01/21 17:59:26
Done.
| |
| 396 | 396 |
| 397 // We can't call UninstallExtension with an invalid extension ID, so check it | 397 // We can't call UninstallExtension with an invalid extension ID, so check it |
| 398 // first. | 398 // first. |
| 399 if (extensions_service->GetExtensionById(extension_id, true)) { | 399 if (extensions_service->GetExtensionById(extension_id, true)) { |
| 400 extensions_service->UninstallExtension(extension_id, false); | 400 extensions_service->UninstallExtension(extension_id, false); |
| 401 } else { | 401 } else { |
| 402 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " | 402 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " |
| 403 << "id: " << extension_id; | 403 << "id: " << extension_id; |
| 404 return false; | 404 return false; |
| 405 } | 405 } |
| 406 | 406 |
| 407 return true; | 407 return true; |
| 408 } | 408 } |
| 409 | 409 |
| 410 ExtensionService::ExtensionService(Profile* profile, | 410 ExtensionService::ExtensionService(Profile* profile, |
| 411 const CommandLine* command_line, | 411 const CommandLine* command_line, |
| 412 const FilePath& install_directory, | 412 const FilePath& install_directory, |
| 413 ExtensionPrefs* extension_prefs, | 413 ExtensionPrefs* extension_prefs, |
| 414 bool autoupdate_enabled) | 414 bool autoupdate_enabled) |
| 415 : profile_(profile), | 415 : profile_(profile), |
| 416 extension_prefs_(extension_prefs), | 416 extension_prefs_(extension_prefs), |
| 417 install_directory_(install_directory), | 417 install_directory_(install_directory), |
| 418 extensions_enabled_(true), | 418 extensions_enabled_(true), |
| 419 show_extensions_prompts_(true), | 419 show_extensions_prompts_(true), |
| 420 ready_(false), | 420 ready_(false), |
| 421 ALLOW_THIS_IN_INITIALIZER_LIST(toolbar_model_(this)), | 421 ALLOW_THIS_IN_INITIALIZER_LIST(toolbar_model_(this)), |
| 422 default_apps_(profile->GetPrefs(), | 422 default_apps_(profile->GetPrefs(), |
| 423 g_browser_process->GetApplicationLocale()), | 423 g_browser_process->GetApplicationLocale()), |
| 424 event_routers_initialized_(false) { | 424 event_routers_initialized_(false) { |
| 425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 425 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 426 | 426 |
| 427 // Figure out if extension installation should be enabled. | 427 // Figure out if extension installation should be enabled. |
| 428 if (command_line->HasSwitch(switches::kDisableExtensions)) { | 428 if (command_line->HasSwitch(switches::kDisableExtensions)) { |
| 429 extensions_enabled_ = false; | 429 extensions_enabled_ = false; |
| 430 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { | 430 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { |
| 431 extensions_enabled_ = false; | 431 extensions_enabled_ = false; |
| 432 } | 432 } |
| 433 | 433 |
| 434 registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED, | 434 registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED, |
| 435 NotificationService::AllSources()); | 435 NotificationService::AllSources()); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 512 ExtensionWebNavigationEventRouter::GetInstance()->Init(); | 512 ExtensionWebNavigationEventRouter::GetInstance()->Init(); |
| 513 event_routers_initialized_ = true; | 513 event_routers_initialized_ = true; |
| 514 } | 514 } |
| 515 | 515 |
| 516 const Extension* ExtensionService::GetExtensionById(const std::string& id, | 516 const Extension* ExtensionService::GetExtensionById(const std::string& id, |
| 517 bool include_disabled) { | 517 bool include_disabled) { |
| 518 return GetExtensionByIdInternal(id, true, include_disabled); | 518 return GetExtensionByIdInternal(id, true, include_disabled); |
| 519 } | 519 } |
| 520 | 520 |
| 521 void ExtensionService::Init() { | 521 void ExtensionService::Init() { |
| 522 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 522 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 523 | 523 |
| 524 DCHECK(!ready_); // Can't redo init. | 524 DCHECK(!ready_); // Can't redo init. |
| 525 DCHECK_EQ(extensions_.size(), 0u); | 525 DCHECK_EQ(extensions_.size(), 0u); |
| 526 | 526 |
| 527 // Hack: we need to ensure the ResourceDispatcherHost is ready before we load | 527 // Hack: we need to ensure the ResourceDispatcherHost is ready before we load |
| 528 // the first extension, because its members listen for loaded notifications. | 528 // the first extension, because its members listen for loaded notifications. |
| 529 g_browser_process->resource_dispatcher_host(); | 529 g_browser_process->resource_dispatcher_host(); |
| 530 | 530 |
| 531 LoadAllExtensions(); | 531 LoadAllExtensions(); |
| 532 | 532 |
| 533 // TODO(erikkay) this should probably be deferred to a future point | 533 // TODO(erikkay) this should probably be deferred to a future point |
| 534 // rather than running immediately at startup. | 534 // rather than running immediately at startup. |
| 535 CheckForExternalUpdates(); | 535 CheckForExternalUpdates(); |
| 536 | 536 |
| 537 // TODO(erikkay) this should probably be deferred as well. | 537 // TODO(erikkay) this should probably be deferred as well. |
| 538 GarbageCollectExtensions(); | 538 GarbageCollectExtensions(); |
| 539 } | 539 } |
| 540 | 540 |
| 541 void ExtensionService::InstallExtension(const FilePath& extension_path) { | 541 void ExtensionService::InstallExtension(const FilePath& extension_path) { |
| 542 scoped_refptr<CrxInstaller> installer( | 542 scoped_refptr<CrxInstaller> installer( |
| 543 new CrxInstaller(this, // frontend | 543 new CrxInstaller(this, // frontend |
| 544 NULL)); // no client (silent install) | 544 NULL)); // no client (silent install) |
| 545 installer->InstallCrx(extension_path); | 545 installer->InstallCrx(extension_path); |
| 546 } | 546 } |
| 547 | 547 |
| 548 namespace { | 548 namespace { |
| 549 // TODO(akalin): Put this somewhere where both crx_installer.cc and | 549 // TODO(akalin): Put this somewhere where both crx_installer.cc and |
| 550 // this file can use it. | 550 // this file can use it. |
| 551 void DeleteFileHelper(const FilePath& path, bool recursive) { | 551 void DeleteFileHelper(const FilePath& path, bool recursive) { |
| 552 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 552 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 553 file_util::Delete(path, recursive); | 553 file_util::Delete(path, recursive); |
| 554 } | 554 } |
| 555 } // namespace | 555 } // namespace |
| 556 | 556 |
| 557 void ExtensionService::UpdateExtension(const std::string& id, | 557 void ExtensionService::UpdateExtension(const std::string& id, |
| 558 const FilePath& extension_path, | 558 const FilePath& extension_path, |
| 559 const GURL& download_url) { | 559 const GURL& download_url) { |
| 560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 560 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 561 | 561 |
| 562 PendingExtensionMap::const_iterator it = pending_extensions_.find(id); | 562 PendingExtensionMap::const_iterator it = pending_extensions_.find(id); |
| 563 bool is_pending_extension = (it != pending_extensions_.end()); | 563 bool is_pending_extension = (it != pending_extensions_.end()); |
| 564 | 564 |
| 565 const Extension* extension = GetExtensionByIdInternal(id, true, true); | 565 const Extension* extension = GetExtensionByIdInternal(id, true, true); |
| 566 if (!is_pending_extension && !extension) { | 566 if (!is_pending_extension && !extension) { |
| 567 LOG(WARNING) << "Will not update extension " << id | 567 LOG(WARNING) << "Will not update extension " << id |
| 568 << " because it is not installed or pending"; | 568 << " because it is not installed or pending"; |
| 569 // Delete extension_path since we're not creating a CrxInstaller | 569 // Delete extension_path since we're not creating a CrxInstaller |
| 570 // that would do it for us. | 570 // that would do it for us. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 kEnableOnInstall, kEnableIncognitoOnInstall, | 668 kEnableOnInstall, kEnableIncognitoOnInstall, |
| 669 Extension::INTERNAL); | 669 Extension::INTERNAL); |
| 670 } | 670 } |
| 671 | 671 |
| 672 void ExtensionService::AddPendingExtensionInternal( | 672 void ExtensionService::AddPendingExtensionInternal( |
| 673 const std::string& id, const GURL& update_url, | 673 const std::string& id, const GURL& update_url, |
| 674 ShouldInstallExtensionPredicate should_install_extension, | 674 ShouldInstallExtensionPredicate should_install_extension, |
| 675 bool is_from_sync, bool install_silently, | 675 bool is_from_sync, bool install_silently, |
| 676 bool enable_on_install, bool enable_incognito_on_install, | 676 bool enable_on_install, bool enable_incognito_on_install, |
| 677 Extension::Location install_source) { | 677 Extension::Location install_source) { |
| 678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 678 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 679 | 679 |
| 680 // If a non-sync update is pending, a sync request should not | 680 // If a non-sync update is pending, a sync request should not |
| 681 // overwrite it. This is important for external extensions. | 681 // overwrite it. This is important for external extensions. |
| 682 // If an external extension download is pending, and the user has | 682 // If an external extension download is pending, and the user has |
| 683 // the extension in their sync profile, the install should set the | 683 // the extension in their sync profile, the install should set the |
| 684 // type to be external. An external extension should not be | 684 // type to be external. An external extension should not be |
| 685 // rejected if it fails the safty checks for a syncable extension. | 685 // rejected if it fails the safty checks for a syncable extension. |
| 686 // TODO(skerner): Work out other potential overlapping conditions. | 686 // TODO(skerner): Work out other potential overlapping conditions. |
| 687 // (crbug.com/61000) | 687 // (crbug.com/61000) |
| 688 PendingExtensionMap::iterator it = pending_extensions_.find(id); | 688 PendingExtensionMap::iterator it = pending_extensions_.find(id); |
| 689 if (it != pending_extensions_.end()) { | 689 if (it != pending_extensions_.end()) { |
| 690 VLOG(1) << "Extension id " << id | 690 VLOG(1) << "Extension id " << id |
| 691 << " was entered for update more than once." | 691 << " was entered for update more than once." |
| 692 << " old is_from_sync = " << it->second.is_from_sync | 692 << " old is_from_sync = " << it->second.is_from_sync |
| 693 << " new is_from_sync = " << is_from_sync; | 693 << " new is_from_sync = " << is_from_sync; |
| 694 if (!it->second.is_from_sync && is_from_sync) | 694 if (!it->second.is_from_sync && is_from_sync) |
| 695 return; | 695 return; |
| 696 } | 696 } |
| 697 | 697 |
| 698 pending_extensions_[id] = | 698 pending_extensions_[id] = |
| 699 PendingExtensionInfo(update_url, should_install_extension, | 699 PendingExtensionInfo(update_url, should_install_extension, |
| 700 is_from_sync, install_silently, enable_on_install, | 700 is_from_sync, install_silently, enable_on_install, |
| 701 enable_incognito_on_install, install_source); | 701 enable_incognito_on_install, install_source); |
| 702 } | 702 } |
| 703 | 703 |
| 704 void ExtensionService::ReloadExtension(const std::string& extension_id) { | 704 void ExtensionService::ReloadExtension(const std::string& extension_id) { |
| 705 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 705 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 706 FilePath path; | 706 FilePath path; |
| 707 const Extension* current_extension = GetExtensionById(extension_id, false); | 707 const Extension* current_extension = GetExtensionById(extension_id, false); |
| 708 | 708 |
| 709 // Disable the extension if it's loaded. It might not be loaded if it crashed. | 709 // Disable the extension if it's loaded. It might not be loaded if it crashed. |
| 710 if (current_extension) { | 710 if (current_extension) { |
| 711 // If the extension has an inspector open for its background page, detach | 711 // If the extension has an inspector open for its background page, detach |
| 712 // the inspector and hang onto a cookie for it, so that we can reattach | 712 // the inspector and hang onto a cookie for it, so that we can reattach |
| 713 // later. | 713 // later. |
| 714 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager(); | 714 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager(); |
| 715 ExtensionHost* host = manager->GetBackgroundHostForExtension( | 715 ExtensionHost* host = manager->GetBackgroundHostForExtension( |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 739 } else { | 739 } else { |
| 740 // We should always be able to remember the extension's path. If it's not in | 740 // We should always be able to remember the extension's path. If it's not in |
| 741 // the map, someone failed to update |unloaded_extension_paths_|. | 741 // the map, someone failed to update |unloaded_extension_paths_|. |
| 742 CHECK(!path.empty()); | 742 CHECK(!path.empty()); |
| 743 LoadExtension(path); | 743 LoadExtension(path); |
| 744 } | 744 } |
| 745 } | 745 } |
| 746 | 746 |
| 747 void ExtensionService::UninstallExtension(const std::string& extension_id, | 747 void ExtensionService::UninstallExtension(const std::string& extension_id, |
| 748 bool external_uninstall) { | 748 bool external_uninstall) { |
| 749 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 749 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 750 | 750 |
| 751 const Extension* extension = | 751 const Extension* extension = |
| 752 GetExtensionByIdInternal(extension_id, true, true); | 752 GetExtensionByIdInternal(extension_id, true, true); |
| 753 | 753 |
| 754 // Callers should not send us nonexistent extensions. | 754 // Callers should not send us nonexistent extensions. |
| 755 CHECK(extension); | 755 CHECK(extension); |
| 756 | 756 |
| 757 // Get hold of information we need after unloading, since the extension | 757 // Get hold of information we need after unloading, since the extension |
| 758 // pointer will be invalid then. | 758 // pointer will be invalid then. |
| 759 GURL extension_url(extension->url()); | 759 GURL extension_url(extension->url()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 Details<UninstalledExtensionInfo>(&uninstalled_extension_info)); | 796 Details<UninstalledExtensionInfo>(&uninstalled_extension_info)); |
| 797 } | 797 } |
| 798 | 798 |
| 799 void ExtensionService::ClearExtensionData(const GURL& extension_url) { | 799 void ExtensionService::ClearExtensionData(const GURL& extension_url) { |
| 800 scoped_refptr<ExtensionDataDeleter> deleter( | 800 scoped_refptr<ExtensionDataDeleter> deleter( |
| 801 new ExtensionDataDeleter(profile_, extension_url)); | 801 new ExtensionDataDeleter(profile_, extension_url)); |
| 802 deleter->StartDeleting(); | 802 deleter->StartDeleting(); |
| 803 } | 803 } |
| 804 | 804 |
| 805 void ExtensionService::EnableExtension(const std::string& extension_id) { | 805 void ExtensionService::EnableExtension(const std::string& extension_id) { |
| 806 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 806 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 807 | 807 |
| 808 const Extension* extension = | 808 const Extension* extension = |
| 809 GetExtensionByIdInternal(extension_id, false, true); | 809 GetExtensionByIdInternal(extension_id, false, true); |
| 810 if (!extension) | 810 if (!extension) |
| 811 return; | 811 return; |
| 812 | 812 |
| 813 extension_prefs_->SetExtensionState(extension, Extension::ENABLED); | 813 extension_prefs_->SetExtensionState(extension, Extension::ENABLED); |
| 814 | 814 |
| 815 // Move it over to the enabled list. | 815 // Move it over to the enabled list. |
| 816 extensions_.push_back(make_scoped_refptr(extension)); | 816 extensions_.push_back(make_scoped_refptr(extension)); |
| 817 ExtensionList::iterator iter = std::find(disabled_extensions_.begin(), | 817 ExtensionList::iterator iter = std::find(disabled_extensions_.begin(), |
| 818 disabled_extensions_.end(), | 818 disabled_extensions_.end(), |
| 819 extension); | 819 extension); |
| 820 disabled_extensions_.erase(iter); | 820 disabled_extensions_.erase(iter); |
| 821 | 821 |
| 822 // Make sure any browser action contained within it is not hidden. | 822 // Make sure any browser action contained within it is not hidden. |
| 823 extension_prefs_->SetBrowserActionVisibility(extension, true); | 823 extension_prefs_->SetBrowserActionVisibility(extension, true); |
| 824 | 824 |
| 825 ExtensionDOMUI::RegisterChromeURLOverrides(profile_, | 825 ExtensionDOMUI::RegisterChromeURLOverrides(profile_, |
| 826 extension->GetChromeURLOverrides()); | 826 extension->GetChromeURLOverrides()); |
| 827 | 827 |
| 828 NotifyExtensionLoaded(extension); | 828 NotifyExtensionLoaded(extension); |
| 829 UpdateActiveExtensionsInCrashReporter(); | 829 UpdateActiveExtensionsInCrashReporter(); |
| 830 } | 830 } |
| 831 | 831 |
| 832 void ExtensionService::DisableExtension(const std::string& extension_id) { | 832 void ExtensionService::DisableExtension(const std::string& extension_id) { |
| 833 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 833 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 834 | 834 |
| 835 const Extension* extension = | 835 const Extension* extension = |
| 836 GetExtensionByIdInternal(extension_id, true, false); | 836 GetExtensionByIdInternal(extension_id, true, false); |
| 837 // The extension may have been disabled already. | 837 // The extension may have been disabled already. |
| 838 if (!extension) | 838 if (!extension) |
| 839 return; | 839 return; |
| 840 | 840 |
| 841 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); | 841 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); |
| 842 | 842 |
| 843 // Move it over to the disabled list. | 843 // Move it over to the disabled list. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 905 if (!extension.get()) { | 905 if (!extension.get()) { |
| 906 NOTREACHED() << error; | 906 NOTREACHED() << error; |
| 907 return; | 907 return; |
| 908 } | 908 } |
| 909 | 909 |
| 910 OnExtensionLoaded(extension); | 910 OnExtensionLoaded(extension); |
| 911 } | 911 } |
| 912 } | 912 } |
| 913 | 913 |
| 914 void ExtensionService::LoadAllExtensions() { | 914 void ExtensionService::LoadAllExtensions() { |
| 915 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 915 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 916 | 916 |
| 917 base::TimeTicks start_time = base::TimeTicks::Now(); | 917 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 918 | 918 |
| 919 // Load any component extensions. | 919 // Load any component extensions. |
| 920 LoadComponentExtensions(); | 920 LoadComponentExtensions(); |
| 921 | 921 |
| 922 // Load the previously installed extensions. | 922 // Load the previously installed extensions. |
| 923 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( | 923 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( |
| 924 extension_prefs_->GetInstalledExtensionsInfo()); | 924 extension_prefs_->GetInstalledExtensionsInfo()); |
| 925 | 925 |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1331 | 1331 |
| 1332 // Some extensions will autoupdate themselves externally from Chrome. These | 1332 // Some extensions will autoupdate themselves externally from Chrome. These |
| 1333 // are typically part of some larger client application package. To support | 1333 // are typically part of some larger client application package. To support |
| 1334 // these, the extension will register its location in the the preferences file | 1334 // these, the extension will register its location in the the preferences file |
| 1335 // (and also, on Windows, in the registry) and this code will periodically | 1335 // (and also, on Windows, in the registry) and this code will periodically |
| 1336 // check that location for a .crx file, which it will then install locally if | 1336 // check that location for a .crx file, which it will then install locally if |
| 1337 // a new version is available. | 1337 // a new version is available. |
| 1338 // Errors are reported through ExtensionErrorReporter. Succcess is not | 1338 // Errors are reported through ExtensionErrorReporter. Succcess is not |
| 1339 // reported. | 1339 // reported. |
| 1340 void ExtensionService::CheckForExternalUpdates() { | 1340 void ExtensionService::CheckForExternalUpdates() { |
| 1341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1341 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1342 | 1342 |
| 1343 // Note that this installation is intentionally silent (since it didn't | 1343 // Note that this installation is intentionally silent (since it didn't |
| 1344 // go through the front-end). Extensions that are registered in this | 1344 // go through the front-end). Extensions that are registered in this |
| 1345 // way are effectively considered 'pre-bundled', and so implicitly | 1345 // way are effectively considered 'pre-bundled', and so implicitly |
| 1346 // trusted. In general, if something has HKLM or filesystem access, | 1346 // trusted. In general, if something has HKLM or filesystem access, |
| 1347 // they could install an extension manually themselves anyway. | 1347 // they could install an extension manually themselves anyway. |
| 1348 external_extension_added_ = false; | 1348 |
| 1349 // If any external extension records give a URL, a provider will set | |
| 1350 // this to true. Used by OnExternalProviderReady() to see if we need | |
| 1351 // to start an update check to fetch a new external extension. | |
| 1352 external_extension_url_added_ = false; | |
| 1349 | 1353 |
| 1350 // Ask each external extension provider to give us a call back for each | 1354 // Ask each external extension provider to give us a call back for each |
| 1351 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. | 1355 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. |
| 1352 ProviderCollection::const_iterator i; | 1356 ProviderCollection::const_iterator i; |
| 1353 for (i = external_extension_providers_.begin(); | 1357 for (i = external_extension_providers_.begin(); |
| 1354 i != external_extension_providers_.end(); ++i) { | 1358 i != external_extension_providers_.end(); ++i) { |
| 1355 ExternalExtensionProviderInterface* provider = i->get(); | 1359 ExternalExtensionProviderInterface* provider = i->get(); |
| 1356 provider->VisitRegisteredExtension(); | 1360 provider->VisitRegisteredExtension(); |
| 1357 } | 1361 } |
| 1358 | 1362 |
| 1359 // Uninstall of unclaimed extensions will happen after all the providers | 1363 // Uninstall of unclaimed extensions will happen after all the providers |
| 1360 // had reported ready. Trigger uninstall even if there are no providers | 1364 // had reported ready. Every provider calls OnExternalProviderReady() |
| 1361 // installed: | 1365 // when it finishes, and OnExternalProviderReady() only acts when all |
| 1362 OnExternalProviderReady(); | 1366 // providers are ready. In case there are no providers, we call it |
| 1367 // to trigger removal of extensions that used to have an external source. | |
| 1368 if (external_extension_providers_.empty()) | |
| 1369 OnExternalProviderReady(); | |
| 1363 } | 1370 } |
| 1364 | 1371 |
| 1365 void ExtensionService::OnExternalProviderReady() { | 1372 void ExtensionService::OnExternalProviderReady() { |
| 1366 // An external provider has finished loading. We only take action | 1373 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1374 | |
| 1375 // An external provider has finished loading. We only take action | |
| 1367 // if all of them are finished. So we check them first. | 1376 // if all of them are finished. So we check them first. |
| 1368 ProviderCollection::const_iterator i; | 1377 ProviderCollection::const_iterator i; |
| 1369 for (i = external_extension_providers_.begin(); | 1378 for (i = external_extension_providers_.begin(); |
| 1370 i != external_extension_providers_.end(); ++i) { | 1379 i != external_extension_providers_.end(); ++i) { |
| 1371 ExternalExtensionProviderInterface* provider = i->get(); | 1380 ExternalExtensionProviderInterface* provider = i->get(); |
| 1372 if (!provider->IsReady()) { | 1381 if (!provider->IsReady()) |
| 1373 return; | 1382 return; |
| 1374 } | |
| 1375 } | 1383 } |
| 1376 | 1384 |
| 1377 // All the providers are ready. Install any pending extensions. | 1385 // All the providers are ready. Install any pending extensions. |
| 1378 if (external_extension_added_ && updater()) { | 1386 if (external_extension_url_added_ && updater()) { |
| 1379 external_extension_added_ = false; | 1387 external_extension_url_added_ = false; |
| 1380 updater()->CheckNow(); | 1388 updater()->CheckNow(); |
| 1381 } | 1389 } |
| 1382 | 1390 |
| 1383 // Uninstall all the unclaimed extensions. | 1391 // Uninstall all the unclaimed extensions. |
| 1384 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( | 1392 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( |
| 1385 extension_prefs_->GetInstalledExtensionsInfo()); | 1393 extension_prefs_->GetInstalledExtensionsInfo()); |
| 1386 for (size_t i = 0; i < extensions_info->size(); ++i) { | 1394 for (size_t i = 0; i < extensions_info->size(); ++i) { |
| 1387 ExtensionInfo* info = extensions_info->at(i).get(); | 1395 ExtensionInfo* info = extensions_info->at(i).get(); |
| 1388 if (Extension::IsExternalLocation(info->extension_location)) | 1396 if (Extension::IsExternalLocation(info->extension_location)) |
| 1389 CheckExternalUninstall(info->extension_id); | 1397 CheckExternalUninstall(info->extension_id); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1642 for (size_t i = 0; i < extensions_.size(); ++i) { | 1650 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 1643 if (!extensions_[i]->is_theme() && | 1651 if (!extensions_[i]->is_theme() && |
| 1644 extensions_[i]->location() != Extension::COMPONENT) | 1652 extensions_[i]->location() != Extension::COMPONENT) |
| 1645 extension_ids.insert(extensions_[i]->id()); | 1653 extension_ids.insert(extensions_[i]->id()); |
| 1646 } | 1654 } |
| 1647 | 1655 |
| 1648 child_process_logging::SetActiveExtensions(extension_ids); | 1656 child_process_logging::SetActiveExtensions(extension_ids); |
| 1649 } | 1657 } |
| 1650 | 1658 |
| 1651 void ExtensionService::OnExtensionInstalled(const Extension* extension) { | 1659 void ExtensionService::OnExtensionInstalled(const Extension* extension) { |
| 1652 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1660 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1653 | 1661 |
| 1654 // Ensure extension is deleted unless we transfer ownership. | 1662 // Ensure extension is deleted unless we transfer ownership. |
| 1655 scoped_refptr<const Extension> scoped_extension(extension); | 1663 scoped_refptr<const Extension> scoped_extension(extension); |
| 1656 Extension::State initial_state = Extension::DISABLED; | 1664 Extension::State initial_state = Extension::DISABLED; |
| 1657 bool initial_enable_incognito = false; | 1665 bool initial_enable_incognito = false; |
| 1658 PendingExtensionMap::iterator it = | 1666 PendingExtensionMap::iterator it = |
| 1659 pending_extensions_.find(extension->id()); | 1667 pending_extensions_.find(extension->id()); |
| 1660 if (it != pending_extensions_.end()) { | 1668 if (it != pending_extensions_.end()) { |
| 1661 PendingExtensionInfo pending_extension_info = it->second; | 1669 PendingExtensionInfo pending_extension_info = it->second; |
| 1662 pending_extensions_.erase(it); | 1670 pending_extensions_.erase(it); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1978 } | 1986 } |
| 1979 | 1987 |
| 1980 void ExtensionService::SetBeingUpgraded(const Extension* extension, | 1988 void ExtensionService::SetBeingUpgraded(const Extension* extension, |
| 1981 bool value) { | 1989 bool value) { |
| 1982 extension_runtime_data_[extension->id()].being_upgraded = value; | 1990 extension_runtime_data_[extension->id()].being_upgraded = value; |
| 1983 } | 1991 } |
| 1984 | 1992 |
| 1985 PropertyBag* ExtensionService::GetPropertyBag(const Extension* extension) { | 1993 PropertyBag* ExtensionService::GetPropertyBag(const Extension* extension) { |
| 1986 return &extension_runtime_data_[extension->id()].property_bag; | 1994 return &extension_runtime_data_[extension->id()].property_bag; |
| 1987 } | 1995 } |
| OLD | NEW |