| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 <iterator> |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 #include "components/startup_metric_utils/startup_metric_utils.h" | 54 #include "components/startup_metric_utils/startup_metric_utils.h" |
| 55 #include "content/public/browser/devtools_agent_host.h" | 55 #include "content/public/browser/devtools_agent_host.h" |
| 56 #include "content/public/browser/notification_service.h" | 56 #include "content/public/browser/notification_service.h" |
| 57 #include "content/public/browser/render_process_host.h" | 57 #include "content/public/browser/render_process_host.h" |
| 58 #include "content/public/browser/storage_partition.h" | 58 #include "content/public/browser/storage_partition.h" |
| 59 #include "extensions/browser/event_router.h" | 59 #include "extensions/browser/event_router.h" |
| 60 #include "extensions/browser/extension_host.h" | 60 #include "extensions/browser/extension_host.h" |
| 61 #include "extensions/browser/extension_prefs.h" | 61 #include "extensions/browser/extension_prefs.h" |
| 62 #include "extensions/browser/extension_registry.h" | 62 #include "extensions/browser/extension_registry.h" |
| 63 #include "extensions/browser/extension_system.h" | 63 #include "extensions/browser/extension_system.h" |
| 64 #include "extensions/browser/install_flag.h" |
| 64 #include "extensions/browser/pref_names.h" | 65 #include "extensions/browser/pref_names.h" |
| 65 #include "extensions/browser/runtime_data.h" | 66 #include "extensions/browser/runtime_data.h" |
| 66 #include "extensions/browser/update_observer.h" | 67 #include "extensions/browser/update_observer.h" |
| 67 #include "extensions/common/extension_messages.h" | 68 #include "extensions/common/extension_messages.h" |
| 68 #include "extensions/common/feature_switch.h" | 69 #include "extensions/common/feature_switch.h" |
| 69 #include "extensions/common/file_util.h" | 70 #include "extensions/common/file_util.h" |
| 70 #include "extensions/common/manifest_constants.h" | 71 #include "extensions/common/manifest_constants.h" |
| 71 #include "extensions/common/manifest_handlers/background_info.h" | 72 #include "extensions/common/manifest_handlers/background_info.h" |
| 72 #include "extensions/common/manifest_handlers/permissions_parser.h" | 73 #include "extensions/common/manifest_handlers/permissions_parser.h" |
| 73 #include "extensions/common/one_shot_event.h" | 74 #include "extensions/common/one_shot_event.h" |
| (...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1570 const Version old_version(old_version_string); | 1571 const Version old_version(old_version_string); |
| 1571 | 1572 |
| 1572 VLOG(1) << "AddComponentExtension " << extension->name(); | 1573 VLOG(1) << "AddComponentExtension " << extension->name(); |
| 1573 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { | 1574 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { |
| 1574 VLOG(1) << "Component extension " << extension->name() << " (" | 1575 VLOG(1) << "Component extension " << extension->name() << " (" |
| 1575 << extension->id() << ") installing/upgrading from '" | 1576 << extension->id() << ") installing/upgrading from '" |
| 1576 << old_version_string << "' to " << extension->version()->GetString(); | 1577 << old_version_string << "' to " << extension->version()->GetString(); |
| 1577 | 1578 |
| 1578 AddNewOrUpdatedExtension(extension, | 1579 AddNewOrUpdatedExtension(extension, |
| 1579 Extension::ENABLED_COMPONENT, | 1580 Extension::ENABLED_COMPONENT, |
| 1580 extensions::NOT_BLACKLISTED, | 1581 extensions::kInstallFlagNone, |
| 1581 false, | |
| 1582 syncer::StringOrdinal(), | 1582 syncer::StringOrdinal(), |
| 1583 std::string()); | 1583 std::string()); |
| 1584 return; | 1584 return; |
| 1585 } | 1585 } |
| 1586 | 1586 |
| 1587 AddExtension(extension); | 1587 AddExtension(extension); |
| 1588 } | 1588 } |
| 1589 | 1589 |
| 1590 void ExtensionService::UpdateActivePermissions(const Extension* extension) { | 1590 void ExtensionService::UpdateActivePermissions(const Extension* extension) { |
| 1591 // If the extension has used the optional permissions API, it will have a | 1591 // If the extension has used the optional permissions API, it will have a |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1735 | 1735 |
| 1736 // TODO(kalman): This is broken. ExtensionService is per-profile. | 1736 // TODO(kalman): This is broken. ExtensionService is per-profile. |
| 1737 // crash_keys::SetActiveExtensions is per-process. See | 1737 // crash_keys::SetActiveExtensions is per-process. See |
| 1738 // http://crbug.com/355029. | 1738 // http://crbug.com/355029. |
| 1739 crash_keys::SetActiveExtensions(extension_ids); | 1739 crash_keys::SetActiveExtensions(extension_ids); |
| 1740 } | 1740 } |
| 1741 | 1741 |
| 1742 void ExtensionService::OnExtensionInstalled( | 1742 void ExtensionService::OnExtensionInstalled( |
| 1743 const Extension* extension, | 1743 const Extension* extension, |
| 1744 const syncer::StringOrdinal& page_ordinal, | 1744 const syncer::StringOrdinal& page_ordinal, |
| 1745 bool has_requirement_errors, | 1745 int install_flags) { |
| 1746 extensions::BlacklistState blacklist_state, | |
| 1747 bool is_ephemeral, | |
| 1748 bool wait_for_idle) { | |
| 1749 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1746 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1750 | 1747 |
| 1751 const std::string& id = extension->id(); | 1748 const std::string& id = extension->id(); |
| 1752 bool initial_enable = ShouldEnableOnInstall(extension); | 1749 bool initial_enable = ShouldEnableOnInstall(extension); |
| 1753 std::string install_parameter; | 1750 std::string install_parameter; |
| 1754 const extensions::PendingExtensionInfo* pending_extension_info = NULL; | 1751 const extensions::PendingExtensionInfo* pending_extension_info = NULL; |
| 1755 if ((pending_extension_info = pending_extension_manager()->GetById(id))) { | 1752 if ((pending_extension_info = pending_extension_manager()->GetById(id))) { |
| 1756 if (!pending_extension_info->ShouldAllowInstall(extension)) { | 1753 if (!pending_extension_info->ShouldAllowInstall(extension)) { |
| 1757 pending_extension_manager()->Remove(id); | 1754 pending_extension_manager()->Remove(id); |
| 1758 | 1755 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1779 } else { | 1776 } else { |
| 1780 // We explicitly want to re-enable an uninstalled external | 1777 // We explicitly want to re-enable an uninstalled external |
| 1781 // extension; if we're here, that means the user is manually | 1778 // extension; if we're here, that means the user is manually |
| 1782 // installing the extension. | 1779 // installing the extension. |
| 1783 if (extension_prefs_->IsExternalExtensionUninstalled(id)) { | 1780 if (extension_prefs_->IsExternalExtensionUninstalled(id)) { |
| 1784 initial_enable = true; | 1781 initial_enable = true; |
| 1785 } | 1782 } |
| 1786 } | 1783 } |
| 1787 | 1784 |
| 1788 // Unsupported requirements overrides the management policy. | 1785 // Unsupported requirements overrides the management policy. |
| 1789 if (has_requirement_errors) { | 1786 if (install_flags & extensions::kInstallFlagHasRequirementErrors) { |
| 1790 initial_enable = false; | 1787 initial_enable = false; |
| 1791 extension_prefs_->AddDisableReason( | 1788 extension_prefs_->AddDisableReason( |
| 1792 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); | 1789 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); |
| 1793 // If the extension was disabled because of unsupported requirements but | 1790 // If the extension was disabled because of unsupported requirements but |
| 1794 // now supports all requirements after an update and there are not other | 1791 // now supports all requirements after an update and there are not other |
| 1795 // disable reasons, enable it. | 1792 // disable reasons, enable it. |
| 1796 } else if (extension_prefs_->GetDisableReasons(id) == | 1793 } else if (extension_prefs_->GetDisableReasons(id) == |
| 1797 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { | 1794 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { |
| 1798 initial_enable = true; | 1795 initial_enable = true; |
| 1799 extension_prefs_->ClearDisableReasons(id); | 1796 extension_prefs_->ClearDisableReasons(id); |
| 1800 } | 1797 } |
| 1801 | 1798 |
| 1802 if (blacklist_state == extensions::BLACKLISTED_MALWARE) { | 1799 if (install_flags & extensions::kInstallFlagIsBlacklistedForMalware) { |
| 1803 // Installation of a blacklisted extension can happen from sync, policy, | 1800 // Installation of a blacklisted extension can happen from sync, policy, |
| 1804 // etc, where to maintain consistency we need to install it, just never | 1801 // etc, where to maintain consistency we need to install it, just never |
| 1805 // load it (see AddExtension). Usually it should be the job of callers to | 1802 // load it (see AddExtension). Usually it should be the job of callers to |
| 1806 // incercept blacklisted extension earlier (e.g. CrxInstaller, before even | 1803 // incercept blacklisted extension earlier (e.g. CrxInstaller, before even |
| 1807 // showing the install dialogue). | 1804 // showing the install dialogue). |
| 1808 extension_prefs_->AcknowledgeBlacklistedExtension(id); | 1805 extension_prefs_->AcknowledgeBlacklistedExtension(id); |
| 1809 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall", | 1806 UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall", |
| 1810 extension->location(), | 1807 extension->location(), |
| 1811 Manifest::NUM_LOCATIONS); | 1808 Manifest::NUM_LOCATIONS); |
| 1812 } | 1809 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1825 extension->location(), Manifest::NUM_LOCATIONS); | 1822 extension->location(), Manifest::NUM_LOCATIONS); |
| 1826 } | 1823 } |
| 1827 | 1824 |
| 1828 // Certain extension locations are specific enough that we can | 1825 // Certain extension locations are specific enough that we can |
| 1829 // auto-acknowledge any extension that came from one of them. | 1826 // auto-acknowledge any extension that came from one of them. |
| 1830 if (Manifest::IsPolicyLocation(extension->location()) || | 1827 if (Manifest::IsPolicyLocation(extension->location()) || |
| 1831 extension->location() == Manifest::EXTERNAL_COMPONENT) | 1828 extension->location() == Manifest::EXTERNAL_COMPONENT) |
| 1832 AcknowledgeExternalExtension(extension->id()); | 1829 AcknowledgeExternalExtension(extension->id()); |
| 1833 const Extension::State initial_state = | 1830 const Extension::State initial_state = |
| 1834 initial_enable ? Extension::ENABLED : Extension::DISABLED; | 1831 initial_enable ? Extension::ENABLED : Extension::DISABLED; |
| 1835 const bool blacklisted_for_malware = | 1832 if (ShouldDelayExtensionUpdate( |
| 1836 blacklist_state == extensions::BLACKLISTED_MALWARE; | 1833 id, install_flags & extensions::kInstallFlagInstallImmediately)) { |
| 1837 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { | |
| 1838 extension_prefs_->SetDelayedInstallInfo( | 1834 extension_prefs_->SetDelayedInstallInfo( |
| 1839 extension, | 1835 extension, |
| 1840 initial_state, | 1836 initial_state, |
| 1841 blacklisted_for_malware, | 1837 install_flags, |
| 1842 is_ephemeral, | |
| 1843 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, | 1838 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, |
| 1844 page_ordinal, | 1839 page_ordinal, |
| 1845 install_parameter); | 1840 install_parameter); |
| 1846 | 1841 |
| 1847 // Transfer ownership of |extension|. | 1842 // Transfer ownership of |extension|. |
| 1848 delayed_installs_.Insert(extension); | 1843 delayed_installs_.Insert(extension); |
| 1849 | 1844 |
| 1850 // Notify observers that app update is available. | 1845 // Notify observers that app update is available. |
| 1851 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, | 1846 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, |
| 1852 OnAppUpdateAvailable(extension)); | 1847 OnAppUpdateAvailable(extension)); |
| 1853 return; | 1848 return; |
| 1854 } | 1849 } |
| 1855 | 1850 |
| 1856 extensions::SharedModuleService::ImportStatus status = | 1851 extensions::SharedModuleService::ImportStatus status = |
| 1857 shared_module_service_->SatisfyImports(extension); | 1852 shared_module_service_->SatisfyImports(extension); |
| 1858 if (installs_delayed_for_gc_) { | 1853 if (installs_delayed_for_gc_) { |
| 1859 extension_prefs_->SetDelayedInstallInfo( | 1854 extension_prefs_->SetDelayedInstallInfo( |
| 1860 extension, | 1855 extension, |
| 1861 initial_state, | 1856 initial_state, |
| 1862 blacklisted_for_malware, | 1857 install_flags, |
| 1863 is_ephemeral, | |
| 1864 extensions::ExtensionPrefs::DELAY_REASON_GC, | 1858 extensions::ExtensionPrefs::DELAY_REASON_GC, |
| 1865 page_ordinal, | 1859 page_ordinal, |
| 1866 install_parameter); | 1860 install_parameter); |
| 1867 delayed_installs_.Insert(extension); | 1861 delayed_installs_.Insert(extension); |
| 1868 } else if (status != SharedModuleService::IMPORT_STATUS_OK) { | 1862 } else if (status != SharedModuleService::IMPORT_STATUS_OK) { |
| 1869 if (status == SharedModuleService::IMPORT_STATUS_UNSATISFIED) { | 1863 if (status == SharedModuleService::IMPORT_STATUS_UNSATISFIED) { |
| 1870 extension_prefs_->SetDelayedInstallInfo( | 1864 extension_prefs_->SetDelayedInstallInfo( |
| 1871 extension, | 1865 extension, |
| 1872 initial_state, | 1866 initial_state, |
| 1873 blacklisted_for_malware, | 1867 install_flags, |
| 1874 is_ephemeral, | |
| 1875 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS, | 1868 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS, |
| 1876 page_ordinal, | 1869 page_ordinal, |
| 1877 install_parameter); | 1870 install_parameter); |
| 1878 delayed_installs_.Insert(extension); | 1871 delayed_installs_.Insert(extension); |
| 1879 } | 1872 } |
| 1880 } else { | 1873 } else { |
| 1881 AddNewOrUpdatedExtension(extension, | 1874 AddNewOrUpdatedExtension(extension, |
| 1882 initial_state, | 1875 initial_state, |
| 1883 blacklist_state, | 1876 install_flags, |
| 1884 is_ephemeral, | |
| 1885 page_ordinal, | 1877 page_ordinal, |
| 1886 install_parameter); | 1878 install_parameter); |
| 1887 } | 1879 } |
| 1888 } | 1880 } |
| 1889 | 1881 |
| 1890 void ExtensionService::AddNewOrUpdatedExtension( | 1882 void ExtensionService::AddNewOrUpdatedExtension( |
| 1891 const Extension* extension, | 1883 const Extension* extension, |
| 1892 Extension::State initial_state, | 1884 Extension::State initial_state, |
| 1893 extensions::BlacklistState blacklist_state, | 1885 int install_flags, |
| 1894 bool is_ephemeral, | |
| 1895 const syncer::StringOrdinal& page_ordinal, | 1886 const syncer::StringOrdinal& page_ordinal, |
| 1896 const std::string& install_parameter) { | 1887 const std::string& install_parameter) { |
| 1897 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1888 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1898 const bool blacklisted_for_malware = | |
| 1899 blacklist_state == extensions::BLACKLISTED_MALWARE; | |
| 1900 bool was_ephemeral = extension_prefs_->IsEphemeralApp(extension->id()); | 1889 bool was_ephemeral = extension_prefs_->IsEphemeralApp(extension->id()); |
| 1901 extension_prefs_->OnExtensionInstalled(extension, | 1890 extension_prefs_->OnExtensionInstalled( |
| 1902 initial_state, | 1891 extension, initial_state, page_ordinal, install_flags, install_parameter); |
| 1903 blacklisted_for_malware, | |
| 1904 is_ephemeral, | |
| 1905 page_ordinal, | |
| 1906 install_parameter); | |
| 1907 delayed_installs_.Remove(extension->id()); | 1892 delayed_installs_.Remove(extension->id()); |
| 1908 if (InstallVerifier::NeedsVerification(*extension)) | 1893 if (InstallVerifier::NeedsVerification(*extension)) |
| 1909 system_->install_verifier()->VerifyExtension(extension->id()); | 1894 system_->install_verifier()->VerifyExtension(extension->id()); |
| 1910 FinishInstallation(extension, was_ephemeral); | 1895 FinishInstallation(extension, was_ephemeral); |
| 1911 } | 1896 } |
| 1912 | 1897 |
| 1913 void ExtensionService::MaybeFinishDelayedInstallation( | 1898 void ExtensionService::MaybeFinishDelayedInstallation( |
| 1914 const std::string& extension_id) { | 1899 const std::string& extension_id) { |
| 1915 // Check if the extension already got installed. | 1900 // Check if the extension already got installed. |
| 1916 if (!delayed_installs_.Contains(extension_id)) | 1901 if (!delayed_installs_.Contains(extension_id)) |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2331 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { | 2316 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { |
| 2332 return false; | 2317 return false; |
| 2333 } | 2318 } |
| 2334 } | 2319 } |
| 2335 | 2320 |
| 2336 return true; | 2321 return true; |
| 2337 } | 2322 } |
| 2338 | 2323 |
| 2339 bool ExtensionService::ShouldDelayExtensionUpdate( | 2324 bool ExtensionService::ShouldDelayExtensionUpdate( |
| 2340 const std::string& extension_id, | 2325 const std::string& extension_id, |
| 2341 bool wait_for_idle) const { | 2326 bool install_immediately) const { |
| 2342 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; | 2327 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; |
| 2343 | 2328 |
| 2344 // If delayed updates are globally disabled, or just for this extension, | 2329 // If delayed updates are globally disabled, or just for this extension, |
| 2345 // don't delay. | 2330 // don't delay. |
| 2346 if (!install_updates_when_idle_ || !wait_for_idle) | 2331 if (!install_updates_when_idle_ || install_immediately) |
| 2347 return false; | 2332 return false; |
| 2348 | 2333 |
| 2349 const Extension* old = GetInstalledExtension(extension_id); | 2334 const Extension* old = GetInstalledExtension(extension_id); |
| 2350 // If there is no old extension, this is not an update, so don't delay. | 2335 // If there is no old extension, this is not an update, so don't delay. |
| 2351 if (!old) | 2336 if (!old) |
| 2352 return false; | 2337 return false; |
| 2353 | 2338 |
| 2354 if (extensions::BackgroundInfo::HasPersistentBackgroundPage(old)) { | 2339 if (extensions::BackgroundInfo::HasPersistentBackgroundPage(old)) { |
| 2355 // Delay installation if the extension listens for the onUpdateAvailable | 2340 // Delay installation if the extension listens for the onUpdateAvailable |
| 2356 // event. | 2341 // event. |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2549 } | 2534 } |
| 2550 | 2535 |
| 2551 void ExtensionService::OnProfileDestructionStarted() { | 2536 void ExtensionService::OnProfileDestructionStarted() { |
| 2552 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2537 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
| 2553 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2538 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
| 2554 it != ids_to_unload.end(); | 2539 it != ids_to_unload.end(); |
| 2555 ++it) { | 2540 ++it) { |
| 2556 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2541 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
| 2557 } | 2542 } |
| 2558 } | 2543 } |
| OLD | NEW |