| 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/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> |
| 8 #include <set> | 9 #include <set> |
| 9 | 10 |
| 10 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 11 #include "base/bind.h" | 12 #include "base/bind.h" |
| 12 #include "base/callback.h" | 13 #include "base/callback.h" |
| 13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 14 #include "base/file_util.h" | 15 #include "base/file_util.h" |
| 15 #include "base/logging.h" | 16 #include "base/logging.h" |
| 16 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 17 #include "base/path_service.h" | 18 #include "base/path_service.h" |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 const CommandLine* command_line, | 356 const CommandLine* command_line, |
| 356 const FilePath& install_directory, | 357 const FilePath& install_directory, |
| 357 extensions::ExtensionPrefs* extension_prefs, | 358 extensions::ExtensionPrefs* extension_prefs, |
| 358 extensions::Blacklist* blacklist, | 359 extensions::Blacklist* blacklist, |
| 359 bool autoupdate_enabled, | 360 bool autoupdate_enabled, |
| 360 bool extensions_enabled) | 361 bool extensions_enabled) |
| 361 : extensions::Blacklist::Observer(blacklist), | 362 : extensions::Blacklist::Observer(blacklist), |
| 362 profile_(profile), | 363 profile_(profile), |
| 363 system_(extensions::ExtensionSystem::Get(profile)), | 364 system_(extensions::ExtensionSystem::Get(profile)), |
| 364 extension_prefs_(extension_prefs), | 365 extension_prefs_(extension_prefs), |
| 366 blacklist_(blacklist), |
| 365 settings_frontend_(extensions::SettingsFrontend::Create(profile)), | 367 settings_frontend_(extensions::SettingsFrontend::Create(profile)), |
| 366 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 368 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 367 install_directory_(install_directory), | 369 install_directory_(install_directory), |
| 368 extensions_enabled_(extensions_enabled), | 370 extensions_enabled_(extensions_enabled), |
| 369 show_extensions_prompts_(true), | 371 show_extensions_prompts_(true), |
| 370 install_updates_when_idle_(true), | 372 install_updates_when_idle_(true), |
| 371 ready_(false), | 373 ready_(false), |
| 372 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 374 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 373 menu_manager_(profile), | 375 menu_manager_(profile), |
| 374 app_notification_manager_( | 376 app_notification_manager_( |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 } | 462 } |
| 461 | 463 |
| 462 const ExtensionSet* ExtensionService::disabled_extensions() const { | 464 const ExtensionSet* ExtensionService::disabled_extensions() const { |
| 463 return &disabled_extensions_; | 465 return &disabled_extensions_; |
| 464 } | 466 } |
| 465 | 467 |
| 466 const ExtensionSet* ExtensionService::terminated_extensions() const { | 468 const ExtensionSet* ExtensionService::terminated_extensions() const { |
| 467 return &terminated_extensions_; | 469 return &terminated_extensions_; |
| 468 } | 470 } |
| 469 | 471 |
| 470 const ExtensionSet* ExtensionService::GenerateInstalledExtensionsSet() const { | 472 const ExtensionSet* ExtensionService::blacklisted_extensions() const { |
| 471 ExtensionSet* installed_extensions = new ExtensionSet(); | 473 return &blacklisted_extensions_; |
| 474 } |
| 475 |
| 476 scoped_ptr<const ExtensionSet> |
| 477 ExtensionService::GenerateInstalledExtensionsSet() const { |
| 478 scoped_ptr<ExtensionSet> installed_extensions(new ExtensionSet()); |
| 472 installed_extensions->InsertAll(extensions_); | 479 installed_extensions->InsertAll(extensions_); |
| 473 installed_extensions->InsertAll(disabled_extensions_); | 480 installed_extensions->InsertAll(disabled_extensions_); |
| 474 installed_extensions->InsertAll(terminated_extensions_); | 481 installed_extensions->InsertAll(terminated_extensions_); |
| 475 return installed_extensions; | 482 installed_extensions->InsertAll(blacklisted_extensions_); |
| 483 return installed_extensions.PassAs<const ExtensionSet>(); |
| 476 } | 484 } |
| 477 | 485 |
| 478 const ExtensionSet* ExtensionService::GetWipedOutExtensions() const { | 486 scoped_ptr<const ExtensionSet> ExtensionService::GetWipedOutExtensions() const { |
| 479 ExtensionSet* extension_set = new ExtensionSet(); | 487 scoped_ptr<ExtensionSet> extension_set(new ExtensionSet()); |
| 480 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); | 488 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); |
| 481 iter != disabled_extensions_.end(); ++iter) { | 489 iter != disabled_extensions_.end(); ++iter) { |
| 482 int disabled_reason = extension_prefs_->GetDisableReasons((*iter)->id()); | 490 int disabled_reason = extension_prefs_->GetDisableReasons((*iter)->id()); |
| 483 if ((disabled_reason & Extension::DISABLE_SIDELOAD_WIPEOUT) != 0) | 491 if ((disabled_reason & Extension::DISABLE_SIDELOAD_WIPEOUT) != 0) |
| 484 extension_set->Insert(*iter); | 492 extension_set->Insert(*iter); |
| 485 } | 493 } |
| 486 return extension_set; | 494 return extension_set.PassAs<const ExtensionSet>(); |
| 487 } | 495 } |
| 488 | 496 |
| 489 extensions::PendingExtensionManager* | 497 extensions::PendingExtensionManager* |
| 490 ExtensionService::pending_extension_manager() { | 498 ExtensionService::pending_extension_manager() { |
| 491 return &pending_extension_manager_; | 499 return &pending_extension_manager_; |
| 492 } | 500 } |
| 493 | 501 |
| 494 ExtensionService::~ExtensionService() { | 502 ExtensionService::~ExtensionService() { |
| 495 // No need to unload extensions here because they are profile-scoped, and the | 503 // No need to unload extensions here because they are profile-scoped, and the |
| 496 // profile is in the process of being deleted. | 504 // profile is in the process of being deleted. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 push_messaging_event_router_->Shutdown(); | 580 push_messaging_event_router_->Shutdown(); |
| 573 } | 581 } |
| 574 | 582 |
| 575 void ExtensionService::Shutdown() { | 583 void ExtensionService::Shutdown() { |
| 576 // Do nothing for now. | 584 // Do nothing for now. |
| 577 } | 585 } |
| 578 | 586 |
| 579 const Extension* ExtensionService::GetExtensionById( | 587 const Extension* ExtensionService::GetExtensionById( |
| 580 const std::string& id, bool include_disabled) const { | 588 const std::string& id, bool include_disabled) const { |
| 581 int include_mask = INCLUDE_ENABLED; | 589 int include_mask = INCLUDE_ENABLED; |
| 582 if (include_disabled) | 590 if (include_disabled) { |
| 583 include_mask |= INCLUDE_DISABLED; | 591 // Include blacklisted extensions here because there are hundreds of |
| 584 return GetExtensionByIdInternal(id, include_mask); | 592 // callers of this function, and many might assume that this includes those |
| 593 // that have been disabled due to blacklisting. |
| 594 include_mask |= INCLUDE_DISABLED | INCLUDE_BLACKLISTED; |
| 595 } |
| 596 return GetExtensionById(id, include_mask); |
| 597 } |
| 598 |
| 599 const Extension* ExtensionService::GetExtensionById( |
| 600 const std::string& id, int include_mask) const { |
| 601 std::string lowercase_id = StringToLowerASCII(id); |
| 602 if (include_mask & INCLUDE_ENABLED) { |
| 603 const Extension* extension = extensions_.GetByID(lowercase_id); |
| 604 if (extension) |
| 605 return extension; |
| 606 } |
| 607 if (include_mask & INCLUDE_DISABLED) { |
| 608 const Extension* extension = disabled_extensions_.GetByID(lowercase_id); |
| 609 if (extension) |
| 610 return extension; |
| 611 } |
| 612 if (include_mask & INCLUDE_TERMINATED) { |
| 613 const Extension* extension = terminated_extensions_.GetByID(lowercase_id); |
| 614 if (extension) |
| 615 return extension; |
| 616 } |
| 617 if (include_mask & INCLUDE_BLACKLISTED) { |
| 618 const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id); |
| 619 if (extension) |
| 620 return extension; |
| 621 } |
| 622 return NULL; |
| 585 } | 623 } |
| 586 | 624 |
| 587 void ExtensionService::Init() { | 625 void ExtensionService::Init() { |
| 588 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 626 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 589 | 627 |
| 590 DCHECK(!ready_); // Can't redo init. | 628 DCHECK(!ready_); // Can't redo init. |
| 591 DCHECK_EQ(extensions_.size(), 0u); | 629 DCHECK_EQ(extensions_.size(), 0u); |
| 592 | 630 |
| 593 // TODO(mek): It might be cleaner to do the FinishIdleInstallInfo stuff here | 631 // TODO(mek): It might be cleaner to do the FinishIdleInstallInfo stuff here |
| 594 // instead of in installedloader | 632 // instead of in installedloader |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; | 668 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; |
| 631 // Leak the temp file at extension_path. We don't want to add to the disk | 669 // Leak the temp file at extension_path. We don't want to add to the disk |
| 632 // I/O burden at shutdown, we can't rely on the I/O completing anyway, and | 670 // I/O burden at shutdown, we can't rely on the I/O completing anyway, and |
| 633 // the file is in the OS temp directory which should be cleaned up for us. | 671 // the file is in the OS temp directory which should be cleaned up for us. |
| 634 return false; | 672 return false; |
| 635 } | 673 } |
| 636 | 674 |
| 637 const extensions::PendingExtensionInfo* pending_extension_info = | 675 const extensions::PendingExtensionInfo* pending_extension_info = |
| 638 pending_extension_manager()->GetById(id); | 676 pending_extension_manager()->GetById(id); |
| 639 | 677 |
| 640 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 678 const Extension* extension = GetInstalledExtension(id); |
| 641 const Extension* extension = | |
| 642 GetExtensionByIdInternal(id, include_mask); | |
| 643 if (!pending_extension_info && !extension) { | 679 if (!pending_extension_info && !extension) { |
| 644 LOG(WARNING) << "Will not update extension " << id | 680 LOG(WARNING) << "Will not update extension " << id |
| 645 << " because it is not installed or pending"; | 681 << " because it is not installed or pending"; |
| 646 // Delete extension_path since we're not creating a CrxInstaller | 682 // Delete extension_path since we're not creating a CrxInstaller |
| 647 // that would do it for us. | 683 // that would do it for us. |
| 648 if (!GetFileTaskRunner()->PostTask( | 684 if (!GetFileTaskRunner()->PostTask( |
| 649 FROM_HERE, | 685 FROM_HERE, |
| 650 base::Bind( | 686 base::Bind( |
| 651 &extension_file_util::DeleteFile, extension_path, false))) | 687 &extension_file_util::DeleteFile, extension_path, false))) |
| 652 NOTREACHED(); | 688 NOTREACHED(); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 return true; | 919 return true; |
| 884 } | 920 } |
| 885 | 921 |
| 886 bool ExtensionService::IsExtensionEnabled( | 922 bool ExtensionService::IsExtensionEnabled( |
| 887 const std::string& extension_id) const { | 923 const std::string& extension_id) const { |
| 888 if (extensions_.Contains(extension_id) || | 924 if (extensions_.Contains(extension_id) || |
| 889 terminated_extensions_.Contains(extension_id)) { | 925 terminated_extensions_.Contains(extension_id)) { |
| 890 return true; | 926 return true; |
| 891 } | 927 } |
| 892 | 928 |
| 893 if (disabled_extensions_.Contains(extension_id)) | 929 if (disabled_extensions_.Contains(extension_id) || |
| 930 blacklisted_extensions_.Contains(extension_id)) { |
| 894 return false; | 931 return false; |
| 932 } |
| 895 | 933 |
| 896 // If the extension hasn't been loaded yet, check the prefs for it. Assume | 934 // If the extension hasn't been loaded yet, check the prefs for it. Assume |
| 897 // enabled unless otherwise noted. | 935 // enabled unless otherwise noted. |
| 898 return !extension_prefs_->IsExtensionDisabled(extension_id) && | 936 return !extension_prefs_->IsExtensionDisabled(extension_id) && |
| 899 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 937 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
| 900 } | 938 } |
| 901 | 939 |
| 902 bool ExtensionService::IsExternalExtensionUninstalled( | 940 bool ExtensionService::IsExternalExtensionUninstalled( |
| 903 const std::string& extension_id) const { | 941 const std::string& extension_id) const { |
| 904 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 942 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
| 905 } | 943 } |
| 906 | 944 |
| 907 void ExtensionService::EnableExtension(const std::string& extension_id) { | 945 void ExtensionService::EnableExtension(const std::string& extension_id) { |
| 908 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 946 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 909 | 947 |
| 910 if (IsExtensionEnabled(extension_id)) | 948 if (IsExtensionEnabled(extension_id)) |
| 911 return; | 949 return; |
| 912 | 950 |
| 913 int disable_reasons = extension_prefs_->GetDisableReasons(extension_id); | 951 int disable_reasons = extension_prefs_->GetDisableReasons(extension_id); |
| 914 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); | 952 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); |
| 915 extension_prefs_->ClearDisableReasons(extension_id); | 953 extension_prefs_->ClearDisableReasons(extension_id); |
| 916 | 954 |
| 917 const Extension* extension = GetExtensionByIdInternal(extension_id, | 955 const Extension* extension = disabled_extensions_.GetByID(extension_id); |
| 918 INCLUDE_DISABLED); | |
| 919 // This can happen if sync enables an extension that is not | 956 // This can happen if sync enables an extension that is not |
| 920 // installed yet. | 957 // installed yet. |
| 921 if (!extension) | 958 if (!extension) |
| 922 return; | 959 return; |
| 923 | 960 |
| 924 if (IsUnacknowledgedExternalExtension(extension)) { | 961 if (IsUnacknowledgedExternalExtension(extension)) { |
| 925 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", | 962 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", |
| 926 EXTERNAL_EXTENSION_REENABLED, | 963 EXTERNAL_EXTENSION_REENABLED, |
| 927 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 964 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
| 928 AcknowledgeExternalExtension(extension->id()); | 965 AcknowledgeExternalExtension(extension->id()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 959 // |extension| can be NULL if sync disables an extension that is not | 996 // |extension| can be NULL if sync disables an extension that is not |
| 960 // installed yet. | 997 // installed yet. |
| 961 if (extension && | 998 if (extension && |
| 962 !system_->management_policy()->UserMayModifySettings(extension, NULL)) { | 999 !system_->management_policy()->UserMayModifySettings(extension, NULL)) { |
| 963 return; | 1000 return; |
| 964 } | 1001 } |
| 965 | 1002 |
| 966 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); | 1003 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); |
| 967 extension_prefs_->AddDisableReason(extension_id, disable_reason); | 1004 extension_prefs_->AddDisableReason(extension_id, disable_reason); |
| 968 | 1005 |
| 969 int include_mask = INCLUDE_ENABLED | INCLUDE_TERMINATED; | 1006 int include_mask = INCLUDE_EVERYTHING & ~INCLUDE_DISABLED; |
| 970 extension = GetExtensionByIdInternal(extension_id, include_mask); | 1007 extension = GetExtensionById(extension_id, include_mask); |
| 971 if (!extension) | 1008 if (!extension) |
| 972 return; | 1009 return; |
| 973 | 1010 |
| 974 // Move it over to the disabled list. Don't send a second unload notification | 1011 // Move it over to the disabled list. Don't send a second unload notification |
| 975 // for terminated extensions being disabled. | 1012 // for terminated extensions being disabled. |
| 976 disabled_extensions_.Insert(make_scoped_refptr(extension)); | 1013 disabled_extensions_.Insert(make_scoped_refptr(extension)); |
| 977 if (extensions_.Contains(extension->id())) { | 1014 if (extensions_.Contains(extension->id())) { |
| 978 extensions_.Remove(extension->id()); | 1015 extensions_.Remove(extension->id()); |
| 979 NotifyExtensionUnloaded(extension, extension_misc::UNLOAD_REASON_DISABLE); | 1016 NotifyExtensionUnloaded(extension, extension_misc::UNLOAD_REASON_DISABLE); |
| 980 } else { | 1017 } else { |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | 1293 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| 1257 return file_task_runner_; | 1294 return file_task_runner_; |
| 1258 } | 1295 } |
| 1259 | 1296 |
| 1260 extensions::ExtensionUpdater* ExtensionService::updater() { | 1297 extensions::ExtensionUpdater* ExtensionService::updater() { |
| 1261 return updater_.get(); | 1298 return updater_.get(); |
| 1262 } | 1299 } |
| 1263 | 1300 |
| 1264 void ExtensionService::CheckManagementPolicy() { | 1301 void ExtensionService::CheckManagementPolicy() { |
| 1265 std::vector<std::string> to_be_removed; | 1302 std::vector<std::string> to_be_removed; |
| 1303 |
| 1266 // Loop through extensions list, unload installed extensions. | 1304 // Loop through extensions list, unload installed extensions. |
| 1267 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 1305 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
| 1268 iter != extensions_.end(); ++iter) { | 1306 iter != extensions_.end(); ++iter) { |
| 1269 const Extension* extension = (*iter); | 1307 const Extension* extension = (*iter); |
| 1270 if (!system_->management_policy()->UserMayLoad(extension, NULL)) | 1308 if (!system_->management_policy()->UserMayLoad(extension, NULL)) |
| 1271 to_be_removed.push_back(extension->id()); | 1309 to_be_removed.push_back(extension->id()); |
| 1272 } | 1310 } |
| 1273 | 1311 |
| 1274 // UnloadExtension will change the extensions_ list. So, we should | 1312 // UnloadExtension will change the extensions_ list. So, we should |
| 1275 // call it outside the iterator loop. | 1313 // call it outside the iterator loop. |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1819 | 1857 |
| 1820 UpdateExternalExtensionAlert(); | 1858 UpdateExternalExtensionAlert(); |
| 1821 | 1859 |
| 1822 if (!did_show_alert) | 1860 if (!did_show_alert) |
| 1823 extension_error_ui_.reset(); | 1861 extension_error_ui_.reset(); |
| 1824 } | 1862 } |
| 1825 | 1863 |
| 1826 bool ExtensionService::PopulateExtensionErrorUI( | 1864 bool ExtensionService::PopulateExtensionErrorUI( |
| 1827 ExtensionErrorUI* extension_error_ui) { | 1865 ExtensionErrorUI* extension_error_ui) { |
| 1828 bool needs_alert = false; | 1866 bool needs_alert = false; |
| 1867 |
| 1868 // Extensions that are blacklisted. |
| 1869 for (ExtensionSet::const_iterator it = blacklisted_extensions_.begin(); |
| 1870 it != blacklisted_extensions_.end(); ++it) { |
| 1871 std::string id = (*it)->id(); |
| 1872 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(id)) { |
| 1873 extension_error_ui->AddBlacklistedExtension(id); |
| 1874 needs_alert = true; |
| 1875 } |
| 1876 } |
| 1877 |
| 1829 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 1878 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
| 1830 iter != extensions_.end(); ++iter) { | 1879 iter != extensions_.end(); ++iter) { |
| 1831 const Extension* e = *iter; | 1880 const Extension* e = *iter; |
| 1881 |
| 1882 // Extensions disabled by policy. Note: this no longer includes blacklisted |
| 1883 // extensions, though we still show the same UI. |
| 1832 if (!system_->management_policy()->UserMayLoad(e, NULL)) { | 1884 if (!system_->management_policy()->UserMayLoad(e, NULL)) { |
| 1833 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { | 1885 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { |
| 1834 extension_error_ui->AddBlacklistedExtension(e->id()); | 1886 extension_error_ui->AddBlacklistedExtension(e->id()); |
| 1835 needs_alert = true; | 1887 needs_alert = true; |
| 1836 } | 1888 } |
| 1837 } | 1889 } |
| 1890 |
| 1891 // Orphaned extensions. |
| 1838 if (extension_prefs_->IsExtensionOrphaned(e->id())) { | 1892 if (extension_prefs_->IsExtensionOrphaned(e->id())) { |
| 1839 if (!extension_prefs_->IsOrphanedExtensionAcknowledged(e->id())) { | 1893 if (!extension_prefs_->IsOrphanedExtensionAcknowledged(e->id())) { |
| 1840 extension_error_ui->AddOrphanedExtension(e->id()); | 1894 extension_error_ui->AddOrphanedExtension(e->id()); |
| 1841 needs_alert = true; | 1895 needs_alert = true; |
| 1842 } | 1896 } |
| 1843 } | 1897 } |
| 1844 } | 1898 } |
| 1899 |
| 1845 return needs_alert; | 1900 return needs_alert; |
| 1846 } | 1901 } |
| 1847 | 1902 |
| 1848 void ExtensionService::HandleExtensionAlertClosed() { | 1903 void ExtensionService::HandleExtensionAlertClosed() { |
| 1849 extension_error_ui_.reset(); | 1904 extension_error_ui_.reset(); |
| 1850 } | 1905 } |
| 1851 | 1906 |
| 1852 void ExtensionService::HandleExtensionAlertAccept() { | 1907 void ExtensionService::HandleExtensionAlertAccept() { |
| 1853 const ExtensionIdSet* extension_ids = | 1908 const ExtensionIdSet* extension_ids = |
| 1854 extension_error_ui_->get_blacklisted_extension_ids(); | 1909 extension_error_ui_->get_blacklisted_extension_ids(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 } | 1969 } |
| 1915 } else { | 1970 } else { |
| 1916 extensions::RemoveExternalInstallError(this); | 1971 extensions::RemoveExternalInstallError(this); |
| 1917 } | 1972 } |
| 1918 } | 1973 } |
| 1919 | 1974 |
| 1920 void ExtensionService::UnloadExtension( | 1975 void ExtensionService::UnloadExtension( |
| 1921 const std::string& extension_id, | 1976 const std::string& extension_id, |
| 1922 extension_misc::UnloadedExtensionReason reason) { | 1977 extension_misc::UnloadedExtensionReason reason) { |
| 1923 // Make sure the extension gets deleted after we return from this function. | 1978 // Make sure the extension gets deleted after we return from this function. |
| 1924 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 1979 int include_mask = INCLUDE_EVERYTHING & ~INCLUDE_TERMINATED; |
| 1925 scoped_refptr<const Extension> extension( | 1980 scoped_refptr<const Extension> extension( |
| 1926 GetExtensionByIdInternal(extension_id, include_mask)); | 1981 GetExtensionById(extension_id, include_mask)); |
| 1927 | 1982 |
| 1928 // This method can be called via PostTask, so the extension may have been | 1983 // This method can be called via PostTask, so the extension may have been |
| 1929 // unloaded by the time this runs. | 1984 // unloaded by the time this runs. |
| 1930 if (!extension) { | 1985 if (!extension) { |
| 1931 // In case the extension may have crashed/uninstalled. Allow the profile to | 1986 // In case the extension may have crashed/uninstalled. Allow the profile to |
| 1932 // clean up its RequestContexts. | 1987 // clean up its RequestContexts. |
| 1933 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); | 1988 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); |
| 1934 return; | 1989 return; |
| 1935 } | 1990 } |
| 1936 | 1991 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2074 EnableExtension(extension->id()); | 2129 EnableExtension(extension->id()); |
| 2075 | 2130 |
| 2076 // Check if the extension's privileges have changed and disable the | 2131 // Check if the extension's privileges have changed and disable the |
| 2077 // extension if necessary. | 2132 // extension if necessary. |
| 2078 InitializePermissions(extension); | 2133 InitializePermissions(extension); |
| 2079 | 2134 |
| 2080 // If this extension is a sideloaded extension and we've not performed a | 2135 // If this extension is a sideloaded extension and we've not performed a |
| 2081 // wipeout before, we might disable this extension here. | 2136 // wipeout before, we might disable this extension here. |
| 2082 MaybeWipeout(extension); | 2137 MaybeWipeout(extension); |
| 2083 | 2138 |
| 2084 if (extension_prefs_->IsExtensionDisabled(extension->id())) { | 2139 // Communicated to the Blacklist. |
| 2140 std::set<std::string> already_in_blacklist; |
| 2141 |
| 2142 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { |
| 2143 // Don't check the Blacklist yet because it's asynchronous (we do it at |
| 2144 // the end). This pre-emptive check is because we will always store the |
| 2145 // blacklisted state of *installed* extensions in prefs, and it's important |
| 2146 // not to re-enable blacklisted extensions. |
| 2147 blacklisted_extensions_.Insert(extension); |
| 2148 already_in_blacklist.insert(extension->id()); |
| 2149 } else if (extension_prefs_->IsExtensionDisabled(extension->id())) { |
| 2085 disabled_extensions_.Insert(extension); | 2150 disabled_extensions_.Insert(extension); |
| 2086 SyncExtensionChangeIfNeeded(*extension); | 2151 SyncExtensionChangeIfNeeded(*extension); |
| 2087 content::NotificationService::current()->Notify( | 2152 content::NotificationService::current()->Notify( |
| 2088 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 2153 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
| 2089 content::Source<Profile>(profile_), | 2154 content::Source<Profile>(profile_), |
| 2090 content::Details<const Extension>(extension)); | 2155 content::Details<const Extension>(extension)); |
| 2091 | 2156 |
| 2092 if (extension_prefs_->GetDisableReasons(extension->id()) & | 2157 if (extension_prefs_->GetDisableReasons(extension->id()) & |
| 2093 Extension::DISABLE_PERMISSIONS_INCREASE) { | 2158 Extension::DISABLE_PERMISSIONS_INCREASE) { |
| 2094 extensions::AddExtensionDisabledError(this, extension); | 2159 extensions::AddExtensionDisabledError(this, extension); |
| 2095 } | 2160 } |
| 2096 return; | 2161 } else { |
| 2162 // All apps that are displayed in the launcher are ordered by their ordinals |
| 2163 // so we must ensure they have valid ordinals. |
| 2164 if (extension->RequiresSortOrdinal()) { |
| 2165 extension_prefs_->extension_sorting()->EnsureValidOrdinals( |
| 2166 extension->id(), syncer::StringOrdinal()); |
| 2167 } |
| 2168 |
| 2169 extensions_.Insert(extension); |
| 2170 SyncExtensionChangeIfNeeded(*extension); |
| 2171 NotifyExtensionLoaded(extension); |
| 2172 DoPostLoadTasks(extension); |
| 2173 |
| 2174 #if defined(ENABLE_THEMES) |
| 2175 if (extension->is_theme()) { |
| 2176 // Now that the theme extension is visible from outside the |
| 2177 // ExtensionService, notify the ThemeService about the |
| 2178 // newly-installed theme. |
| 2179 ThemeServiceFactory::GetForProfile(profile_)->SetTheme(extension); |
| 2180 } |
| 2181 #endif |
| 2097 } | 2182 } |
| 2098 | 2183 |
| 2099 // All apps that are displayed in the launcher are ordered by their ordinals | 2184 // Lastly, begin the process for checking the blacklist status of extensions. |
| 2100 // so we must ensure they have valid ordinals. | 2185 // This may need to go to other threads so is asynchronous. |
| 2101 if (extension->RequiresSortOrdinal()) { | 2186 std::set<std::string> id_set; |
| 2102 extension_prefs_->extension_sorting()->EnsureValidOrdinals( | 2187 id_set.insert(extension->id()); |
| 2103 extension->id(), syncer::StringOrdinal()); | 2188 blacklist_->GetBlacklistedIDs( |
| 2104 } | 2189 id_set, |
| 2105 | 2190 base::Bind(&ExtensionService::ManageBlacklist, |
| 2106 extensions_.Insert(extension); | 2191 AsWeakPtr(), |
| 2107 SyncExtensionChangeIfNeeded(*extension); | 2192 already_in_blacklist)); |
| 2108 NotifyExtensionLoaded(extension); | |
| 2109 DoPostLoadTasks(extension); | |
| 2110 | |
| 2111 #if defined(ENABLE_THEMES) | |
| 2112 if (extension->is_theme()) { | |
| 2113 // Now that the theme extension is visible from outside the | |
| 2114 // ExtensionService, notify the ThemeService about the | |
| 2115 // newly-installed theme. | |
| 2116 ThemeServiceFactory::GetForProfile(profile_)->SetTheme(extension); | |
| 2117 } | |
| 2118 #endif | |
| 2119 } | 2193 } |
| 2120 | 2194 |
| 2121 void ExtensionService::AddComponentExtension(const Extension* extension) { | 2195 void ExtensionService::AddComponentExtension(const Extension* extension) { |
| 2122 const std::string old_version_string( | 2196 const std::string old_version_string( |
| 2123 extension_prefs_->GetVersionString(extension->id())); | 2197 extension_prefs_->GetVersionString(extension->id())); |
| 2124 const Version old_version(old_version_string); | 2198 const Version old_version(old_version_string); |
| 2125 | 2199 |
| 2126 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { | 2200 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { |
| 2127 VLOG(1) << "Component extension " << extension->name() << " (" | 2201 VLOG(1) << "Component extension " << extension->name() << " (" |
| 2128 << extension->id() << ") installing/upgrading from '" | 2202 << extension->id() << ") installing/upgrading from '" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2181 // maintain backwards compatibility while still having "omnibox" in the | 2255 // maintain backwards compatibility while still having "omnibox" in the |
| 2182 // manifest. If a user installs the extension on Chrome 9, the browser | 2256 // manifest. If a user installs the extension on Chrome 9, the browser |
| 2183 // will record the permissions it recognized, not including "omnibox." | 2257 // will record the permissions it recognized, not including "omnibox." |
| 2184 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome | 2258 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome |
| 2185 // will disable the extension and prompt the user to approve the increase | 2259 // will disable the extension and prompt the user to approve the increase |
| 2186 // in privileges. The extension could then release a new version that | 2260 // in privileges. The extension could then release a new version that |
| 2187 // removes the "omnibox" permission. When the user upgrades, Chrome will | 2261 // removes the "omnibox" permission. When the user upgrades, Chrome will |
| 2188 // still remember that "omnibox" had been granted, so that if the | 2262 // still remember that "omnibox" had been granted, so that if the |
| 2189 // extension once again includes "omnibox" in an upgrade, the extension | 2263 // extension once again includes "omnibox" in an upgrade, the extension |
| 2190 // can upgrade without requiring this user's approval. | 2264 // can upgrade without requiring this user's approval. |
| 2191 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 2265 const Extension* old = GetInstalledExtension(extension->id()); |
| 2192 const Extension* old = | |
| 2193 GetExtensionByIdInternal(extension->id(), include_mask); | |
| 2194 bool is_extension_upgrade = old != NULL; | 2266 bool is_extension_upgrade = old != NULL; |
| 2195 bool is_privilege_increase = false; | 2267 bool is_privilege_increase = false; |
| 2196 bool previously_disabled = false; | 2268 bool previously_disabled = false; |
| 2197 int disable_reasons = extension_prefs_->GetDisableReasons(extension->id()); | 2269 int disable_reasons = extension_prefs_->GetDisableReasons(extension->id()); |
| 2198 | 2270 |
| 2199 // We only need to compare the granted permissions to the current permissions | 2271 // We only need to compare the granted permissions to the current permissions |
| 2200 // if the extension is not allowed to silently increase its permissions. | 2272 // if the extension is not allowed to silently increase its permissions. |
| 2201 bool is_default_app_install = | 2273 bool is_default_app_install = |
| 2202 (!is_extension_upgrade && extension->was_installed_by_default()); | 2274 (!is_extension_upgrade && extension->was_installed_by_default()); |
| 2203 if (!(extension->CanSilentlyIncreasePermissions() | 2275 if (!(extension->CanSilentlyIncreasePermissions() |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2364 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); | 2436 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); |
| 2365 // If the extension was disabled because of unsupported requirements but | 2437 // If the extension was disabled because of unsupported requirements but |
| 2366 // now supports all requirements after an update and there are not other | 2438 // now supports all requirements after an update and there are not other |
| 2367 // disable reasons, enable it. | 2439 // disable reasons, enable it. |
| 2368 } else if (extension_prefs_->GetDisableReasons(id) == | 2440 } else if (extension_prefs_->GetDisableReasons(id) == |
| 2369 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { | 2441 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { |
| 2370 initial_enable = true; | 2442 initial_enable = true; |
| 2371 extension_prefs_->ClearDisableReasons(id); | 2443 extension_prefs_->ClearDisableReasons(id); |
| 2372 } | 2444 } |
| 2373 | 2445 |
| 2374 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 2446 if (!GetInstalledExtension(extension->id())) { |
| 2375 if (!GetExtensionByIdInternal(extension->id(), include_mask)) { | |
| 2376 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", | 2447 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", |
| 2377 extension->GetType(), 100); | 2448 extension->GetType(), 100); |
| 2378 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", | 2449 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", |
| 2379 extension->location(), Extension::NUM_LOCATIONS); | 2450 extension->location(), Extension::NUM_LOCATIONS); |
| 2380 RecordPermissionMessagesHistogram( | 2451 RecordPermissionMessagesHistogram( |
| 2381 extension, "Extensions.Permissions_Install"); | 2452 extension, "Extensions.Permissions_Install"); |
| 2382 } else { | 2453 } else { |
| 2383 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", | 2454 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", |
| 2384 extension->GetType(), 100); | 2455 extension->GetType(), 100); |
| 2385 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", | 2456 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2477 EXTERNAL_EXTENSION_INSTALLED, | 2548 EXTERNAL_EXTENSION_INSTALLED, |
| 2478 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 2549 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
| 2479 } | 2550 } |
| 2480 } | 2551 } |
| 2481 | 2552 |
| 2482 const Extension* ExtensionService::GetPendingExtensionUpdate( | 2553 const Extension* ExtensionService::GetPendingExtensionUpdate( |
| 2483 const std::string& id) const { | 2554 const std::string& id) const { |
| 2484 return pending_extension_updates_.GetByID(id); | 2555 return pending_extension_updates_.GetByID(id); |
| 2485 } | 2556 } |
| 2486 | 2557 |
| 2487 const Extension* ExtensionService::GetExtensionByIdInternal( | |
| 2488 const std::string& id, int include_mask) const { | |
| 2489 std::string lowercase_id = StringToLowerASCII(id); | |
| 2490 if (include_mask & INCLUDE_ENABLED) { | |
| 2491 const Extension* extension = extensions_.GetByID(lowercase_id); | |
| 2492 if (extension) | |
| 2493 return extension; | |
| 2494 } | |
| 2495 if (include_mask & INCLUDE_DISABLED) { | |
| 2496 const Extension* extension = disabled_extensions_.GetByID(lowercase_id); | |
| 2497 if (extension) | |
| 2498 return extension; | |
| 2499 } | |
| 2500 if (include_mask & INCLUDE_TERMINATED) { | |
| 2501 const Extension* extension = terminated_extensions_.GetByID(lowercase_id); | |
| 2502 if (extension) | |
| 2503 return extension; | |
| 2504 } | |
| 2505 return NULL; | |
| 2506 } | |
| 2507 | |
| 2508 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { | 2558 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { |
| 2509 if (!terminated_extensions_.Contains(extension->id())) | 2559 if (!terminated_extensions_.Contains(extension->id())) |
| 2510 terminated_extensions_.Insert(make_scoped_refptr(extension)); | 2560 terminated_extensions_.Insert(make_scoped_refptr(extension)); |
| 2511 | 2561 |
| 2512 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); | 2562 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); |
| 2513 } | 2563 } |
| 2514 | 2564 |
| 2515 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { | 2565 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { |
| 2516 std::string lowercase_id = StringToLowerASCII(id); | 2566 std::string lowercase_id = StringToLowerASCII(id); |
| 2517 terminated_extensions_.Remove(lowercase_id); | 2567 terminated_extensions_.Remove(lowercase_id); |
| 2518 } | 2568 } |
| 2519 | 2569 |
| 2520 const Extension* ExtensionService::GetTerminatedExtension( | 2570 const Extension* ExtensionService::GetTerminatedExtension( |
| 2521 const std::string& id) const { | 2571 const std::string& id) const { |
| 2522 return GetExtensionByIdInternal(id, INCLUDE_TERMINATED); | 2572 return GetExtensionById(id, INCLUDE_TERMINATED); |
| 2523 } | 2573 } |
| 2524 | 2574 |
| 2525 const Extension* ExtensionService::GetInstalledExtension( | 2575 const Extension* ExtensionService::GetInstalledExtension( |
| 2526 const std::string& id) const { | 2576 const std::string& id) const { |
| 2527 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED | INCLUDE_TERMINATED; | 2577 int include_mask = INCLUDE_ENABLED | |
| 2528 return GetExtensionByIdInternal(id, include_mask); | 2578 INCLUDE_DISABLED | |
| 2579 INCLUDE_TERMINATED | |
| 2580 INCLUDE_BLACKLISTED; |
| 2581 return GetExtensionById(id, include_mask); |
| 2529 } | 2582 } |
| 2530 | 2583 |
| 2531 bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) { | 2584 bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) { |
| 2532 // Allow bindings for all packaged extensions and component hosted apps. | 2585 // Allow bindings for all packaged extensions and component hosted apps. |
| 2533 const Extension* extension = extensions_.GetExtensionOrAppByURL( | 2586 const Extension* extension = extensions_.GetExtensionOrAppByURL( |
| 2534 ExtensionURLInfo(url)); | 2587 ExtensionURLInfo(url)); |
| 2535 return extension && (!extension->is_hosted_app() || | 2588 return extension && (!extension->is_hosted_app() || |
| 2536 extension->location() == Extension::COMPONENT); | 2589 extension->location() == Extension::COMPONENT); |
| 2537 } | 2590 } |
| 2538 | 2591 |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3010 bool ExtensionService::ShouldDelayExtensionUpdate( | 3063 bool ExtensionService::ShouldDelayExtensionUpdate( |
| 3011 const std::string& extension_id, | 3064 const std::string& extension_id, |
| 3012 bool wait_for_idle) const { | 3065 bool wait_for_idle) const { |
| 3013 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; | 3066 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; |
| 3014 | 3067 |
| 3015 // If delayed updates are globally disabled, or just for this extension, | 3068 // If delayed updates are globally disabled, or just for this extension, |
| 3016 // don't delay. | 3069 // don't delay. |
| 3017 if (!install_updates_when_idle_ || !wait_for_idle) | 3070 if (!install_updates_when_idle_ || !wait_for_idle) |
| 3018 return false; | 3071 return false; |
| 3019 | 3072 |
| 3020 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 3073 const Extension* old = GetInstalledExtension(extension_id); |
| 3021 const Extension* old = | |
| 3022 GetExtensionByIdInternal(extension_id, include_mask); | |
| 3023 // If there is no old extension, this is not an update, so don't delay. | 3074 // If there is no old extension, this is not an update, so don't delay. |
| 3024 if (!old) | 3075 if (!old) |
| 3025 return false; | 3076 return false; |
| 3026 | 3077 |
| 3027 if (old->has_persistent_background_page()) { | 3078 if (old->has_persistent_background_page()) { |
| 3028 // Delay installation if the extension listens for the onUpdateAvailable | 3079 // Delay installation if the extension listens for the onUpdateAvailable |
| 3029 // event. | 3080 // event. |
| 3030 return system_->event_router()->ExtensionHasEventListener( | 3081 return system_->event_router()->ExtensionHasEventListener( |
| 3031 extension_id, kOnUpdateAvailableEvent); | 3082 extension_id, kOnUpdateAvailableEvent); |
| 3032 } else { | 3083 } else { |
| 3033 // Delay installation if the extension is not idle. | 3084 // Delay installation if the extension is not idle. |
| 3034 return !IsExtensionIdle(extension_id); | 3085 return !IsExtensionIdle(extension_id); |
| 3035 } | 3086 } |
| 3036 } | 3087 } |
| 3037 | 3088 |
| 3038 void ExtensionService::OnBlacklistUpdated() { | 3089 void ExtensionService::OnBlacklistUpdated() { |
| 3039 CheckManagementPolicy(); | 3090 blacklist_->GetBlacklistedIDs( |
| 3091 GenerateInstalledExtensionsSet()->GetIDs(), |
| 3092 base::Bind(&ExtensionService::ManageBlacklist, |
| 3093 AsWeakPtr(), |
| 3094 blacklisted_extensions_.GetIDs())); |
| 3040 } | 3095 } |
| 3096 |
| 3097 void ExtensionService::ManageBlacklist( |
| 3098 const std::set<std::string>& old_blacklisted_ids, |
| 3099 const std::set<std::string>& new_blacklisted_ids) { |
| 3100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 3101 |
| 3102 std::set<std::string> no_longer_blacklisted; |
| 3103 std::set_difference(old_blacklisted_ids.begin(), old_blacklisted_ids.end(), |
| 3104 new_blacklisted_ids.begin(), new_blacklisted_ids.end(), |
| 3105 std::inserter(no_longer_blacklisted, |
| 3106 no_longer_blacklisted.begin())); |
| 3107 std::set<std::string> not_yet_blacklisted; |
| 3108 std::set_difference(new_blacklisted_ids.begin(), new_blacklisted_ids.end(), |
| 3109 old_blacklisted_ids.begin(), old_blacklisted_ids.end(), |
| 3110 std::inserter(not_yet_blacklisted, |
| 3111 not_yet_blacklisted.begin())); |
| 3112 |
| 3113 for (std::set<std::string>::iterator it = no_longer_blacklisted.begin(); |
| 3114 it != no_longer_blacklisted.end(); ++it) { |
| 3115 scoped_refptr<const Extension> extension = |
| 3116 blacklisted_extensions_.GetByID(*it); |
| 3117 DCHECK(extension); |
| 3118 if (!extension) |
| 3119 continue; |
| 3120 blacklisted_extensions_.Remove(*it); |
| 3121 AddExtension(extension); |
| 3122 } |
| 3123 |
| 3124 for (std::set<std::string>::iterator it = not_yet_blacklisted.begin(); |
| 3125 it != not_yet_blacklisted.end(); ++it) { |
| 3126 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); |
| 3127 DCHECK(extension); |
| 3128 if (!extension) |
| 3129 continue; |
| 3130 blacklisted_extensions_.Insert(extension); |
| 3131 UnloadExtension(*it, extension_misc::UNLOAD_REASON_BLACKLIST); |
| 3132 } |
| 3133 |
| 3134 IdentifyAlertableExtensions(); |
| 3135 } |
| OLD | NEW |