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