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 <set> | 8 #include <set> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 #include "chrome/browser/extensions/extension_error_reporter.h" | 53 #include "chrome/browser/extensions/extension_error_reporter.h" |
54 #include "chrome/browser/extensions/extension_error_ui.h" | 54 #include "chrome/browser/extensions/extension_error_ui.h" |
55 #include "chrome/browser/extensions/extension_host.h" | 55 #include "chrome/browser/extensions/extension_host.h" |
56 #include "chrome/browser/extensions/extension_install_ui.h" | 56 #include "chrome/browser/extensions/extension_install_ui.h" |
57 #include "chrome/browser/extensions/extension_process_manager.h" | 57 #include "chrome/browser/extensions/extension_process_manager.h" |
58 #include "chrome/browser/extensions/extension_sorting.h" | 58 #include "chrome/browser/extensions/extension_sorting.h" |
59 #include "chrome/browser/extensions/extension_special_storage_policy.h" | 59 #include "chrome/browser/extensions/extension_special_storage_policy.h" |
60 #include "chrome/browser/extensions/extension_sync_data.h" | 60 #include "chrome/browser/extensions/extension_sync_data.h" |
61 #include "chrome/browser/extensions/extension_system.h" | 61 #include "chrome/browser/extensions/extension_system.h" |
62 #include "chrome/browser/extensions/extension_web_ui.h" | 62 #include "chrome/browser/extensions/extension_web_ui.h" |
| 63 #include "chrome/browser/extensions/external_install_ui.h" |
63 #include "chrome/browser/extensions/external_provider_impl.h" | 64 #include "chrome/browser/extensions/external_provider_impl.h" |
64 #include "chrome/browser/extensions/external_provider_interface.h" | 65 #include "chrome/browser/extensions/external_provider_interface.h" |
65 #include "chrome/browser/extensions/installed_loader.h" | 66 #include "chrome/browser/extensions/installed_loader.h" |
66 #include "chrome/browser/extensions/lazy_background_task_queue.h" | 67 #include "chrome/browser/extensions/lazy_background_task_queue.h" |
67 #include "chrome/browser/extensions/pending_extension_manager.h" | 68 #include "chrome/browser/extensions/pending_extension_manager.h" |
68 #include "chrome/browser/extensions/permissions_updater.h" | 69 #include "chrome/browser/extensions/permissions_updater.h" |
69 #include "chrome/browser/extensions/platform_app_launcher.h" | 70 #include "chrome/browser/extensions/platform_app_launcher.h" |
70 #include "chrome/browser/extensions/settings/settings_frontend.h" | 71 #include "chrome/browser/extensions/settings/settings_frontend.h" |
71 #include "chrome/browser/extensions/shell_window_registry.h" | 72 #include "chrome/browser/extensions/shell_window_registry.h" |
72 #include "chrome/browser/extensions/unpacked_installer.h" | 73 #include "chrome/browser/extensions/unpacked_installer.h" |
(...skipping 17 matching lines...) Expand all Loading... |
90 #include "chrome/common/chrome_paths.h" | 91 #include "chrome/common/chrome_paths.h" |
91 #include "chrome/common/chrome_switches.h" | 92 #include "chrome/common/chrome_switches.h" |
92 #include "chrome/common/chrome_version_info.h" | 93 #include "chrome/common/chrome_version_info.h" |
93 #include "chrome/common/extensions/extension.h" | 94 #include "chrome/common/extensions/extension.h" |
94 #include "chrome/common/extensions/extension_error_utils.h" | 95 #include "chrome/common/extensions/extension_error_utils.h" |
95 #include "chrome/common/extensions/extension_file_util.h" | 96 #include "chrome/common/extensions/extension_file_util.h" |
96 #include "chrome/common/extensions/extension_manifest_constants.h" | 97 #include "chrome/common/extensions/extension_manifest_constants.h" |
97 #include "chrome/common/extensions/extension_messages.h" | 98 #include "chrome/common/extensions/extension_messages.h" |
98 #include "chrome/common/extensions/extension_resource.h" | 99 #include "chrome/common/extensions/extension_resource.h" |
99 #include "chrome/common/extensions/features/feature.h" | 100 #include "chrome/common/extensions/features/feature.h" |
| 101 #include "chrome/common/extensions/feature_switch.h" |
100 #include "chrome/common/pref_names.h" | 102 #include "chrome/common/pref_names.h" |
101 #include "chrome/common/url_constants.h" | 103 #include "chrome/common/url_constants.h" |
102 #include "content/public/browser/browser_thread.h" | 104 #include "content/public/browser/browser_thread.h" |
103 #include "content/public/browser/devtools_agent_host_registry.h" | 105 #include "content/public/browser/devtools_agent_host_registry.h" |
104 #include "content/public/browser/devtools_manager.h" | 106 #include "content/public/browser/devtools_manager.h" |
105 #include "content/public/browser/notification_service.h" | 107 #include "content/public/browser/notification_service.h" |
106 #include "content/public/browser/notification_types.h" | 108 #include "content/public/browser/notification_types.h" |
107 #include "content/public/browser/plugin_service.h" | 109 #include "content/public/browser/plugin_service.h" |
108 #include "content/public/browser/render_process_host.h" | 110 #include "content/public/browser/render_process_host.h" |
109 #include "content/public/common/pepper_plugin_info.h" | 111 #include "content/public/common/pepper_plugin_info.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 static const int kOmniboxIconPaddingLeft = 2; | 151 static const int kOmniboxIconPaddingLeft = 2; |
150 static const int kOmniboxIconPaddingRight = 2; | 152 static const int kOmniboxIconPaddingRight = 2; |
151 #elif defined(OS_MACOSX) | 153 #elif defined(OS_MACOSX) |
152 static const int kOmniboxIconPaddingLeft = 0; | 154 static const int kOmniboxIconPaddingLeft = 0; |
153 static const int kOmniboxIconPaddingRight = 2; | 155 static const int kOmniboxIconPaddingRight = 2; |
154 #else | 156 #else |
155 static const int kOmniboxIconPaddingLeft = 0; | 157 static const int kOmniboxIconPaddingLeft = 0; |
156 static const int kOmniboxIconPaddingRight = 0; | 158 static const int kOmniboxIconPaddingRight = 0; |
157 #endif | 159 #endif |
158 | 160 |
| 161 // Prompt the user this many times before considering an extension acknowledged. |
| 162 static const int kMaxExtensionAcknowledgePromptCount = 3; |
| 163 |
159 const char* kNaClPluginMimeType = "application/x-nacl"; | 164 const char* kNaClPluginMimeType = "application/x-nacl"; |
160 | 165 |
161 static bool IsSyncableExtension(const Extension& extension) { | 166 static bool IsSyncableExtension(const Extension& extension) { |
162 return extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION; | 167 return extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION; |
163 } | 168 } |
164 | 169 |
165 static bool IsSyncableApp(const Extension& extension) { | 170 static bool IsSyncableApp(const Extension& extension) { |
166 return extension.GetSyncType() == Extension::SYNC_TYPE_APP; | 171 return extension.GetSyncType() == Extension::SYNC_TYPE_APP; |
167 } | 172 } |
168 | 173 |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); | 864 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); |
860 extension_prefs_->ClearDisableReasons(extension_id); | 865 extension_prefs_->ClearDisableReasons(extension_id); |
861 | 866 |
862 const Extension* extension = GetExtensionByIdInternal(extension_id, | 867 const Extension* extension = GetExtensionByIdInternal(extension_id, |
863 INCLUDE_DISABLED); | 868 INCLUDE_DISABLED); |
864 // This can happen if sync enables an extension that is not | 869 // This can happen if sync enables an extension that is not |
865 // installed yet. | 870 // installed yet. |
866 if (!extension) | 871 if (!extension) |
867 return; | 872 return; |
868 | 873 |
| 874 if (Extension::IsExternalLocation(extension->location())) |
| 875 AcknowledgeExternalExtension(extension->id()); |
| 876 |
869 // Move it over to the enabled list. | 877 // Move it over to the enabled list. |
870 extensions_.Insert(make_scoped_refptr(extension)); | 878 extensions_.Insert(make_scoped_refptr(extension)); |
871 disabled_extensions_.Remove(extension->id()); | 879 disabled_extensions_.Remove(extension->id()); |
872 | 880 |
873 // Make sure any browser action contained within it is not hidden. | 881 // Make sure any browser action contained within it is not hidden. |
874 extension_prefs_->SetBrowserActionVisibility(extension, true); | 882 extension_prefs_->SetBrowserActionVisibility(extension, true); |
875 | 883 |
876 NotifyExtensionLoaded(extension); | 884 NotifyExtensionLoaded(extension); |
877 | 885 |
878 // Notify listeners that the extension was enabled. | 886 // Notify listeners that the extension was enabled. |
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1750 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1758 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1751 did_show_alert = extension_error_ui_->ShowErrorInBubbleView(); | 1759 did_show_alert = extension_error_ui_->ShowErrorInBubbleView(); |
1752 } else { | 1760 } else { |
1753 // First run. Just acknowledge all the extensions, silently, by | 1761 // First run. Just acknowledge all the extensions, silently, by |
1754 // shortcutting the display of the UI and going straight to the | 1762 // shortcutting the display of the UI and going straight to the |
1755 // callback for pressing the Accept button. | 1763 // callback for pressing the Accept button. |
1756 HandleExtensionAlertAccept(); | 1764 HandleExtensionAlertAccept(); |
1757 } | 1765 } |
1758 } | 1766 } |
1759 | 1767 |
| 1768 UpdateExternalExtensionAlert(); |
| 1769 |
1760 if (!did_show_alert) | 1770 if (!did_show_alert) |
1761 extension_error_ui_.reset(); | 1771 extension_error_ui_.reset(); |
1762 } | 1772 } |
1763 | 1773 |
1764 bool ExtensionService::PopulateExtensionErrorUI( | 1774 bool ExtensionService::PopulateExtensionErrorUI( |
1765 ExtensionErrorUI* extension_error_ui) { | 1775 ExtensionErrorUI* extension_error_ui) { |
1766 bool needs_alert = false; | 1776 bool needs_alert = false; |
1767 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 1777 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
1768 iter != extensions_.end(); ++iter) { | 1778 iter != extensions_.end(); ++iter) { |
1769 const Extension* e = *iter; | 1779 const Extension* e = *iter; |
1770 if (Extension::IsExternalLocation(e->location())) { | |
1771 if (!e->is_hosted_app()) { | |
1772 if (!extension_prefs_->IsExternalExtensionAcknowledged(e->id())) { | |
1773 extension_error_ui->AddExternalExtension(e->id()); | |
1774 needs_alert = true; | |
1775 } | |
1776 } | |
1777 } | |
1778 if (!extension_prefs_->UserMayLoad(e, NULL)) { | 1780 if (!extension_prefs_->UserMayLoad(e, NULL)) { |
1779 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { | 1781 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { |
1780 extension_error_ui->AddBlacklistedExtension(e->id()); | 1782 extension_error_ui->AddBlacklistedExtension(e->id()); |
1781 needs_alert = true; | 1783 needs_alert = true; |
1782 } | 1784 } |
1783 } | 1785 } |
1784 if (extension_prefs_->IsExtensionOrphaned(e->id())) { | 1786 if (extension_prefs_->IsExtensionOrphaned(e->id())) { |
1785 if (!extension_prefs_->IsOrphanedExtensionAcknowledged(e->id())) { | 1787 if (!extension_prefs_->IsOrphanedExtensionAcknowledged(e->id())) { |
1786 extension_error_ui->AddOrphanedExtension(e->id()); | 1788 extension_error_ui->AddOrphanedExtension(e->id()); |
1787 needs_alert = true; | 1789 needs_alert = true; |
1788 } | 1790 } |
1789 } | 1791 } |
1790 } | 1792 } |
1791 return needs_alert; | 1793 return needs_alert; |
1792 } | 1794 } |
1793 | 1795 |
1794 void ExtensionService::HandleExtensionAlertClosed() { | 1796 void ExtensionService::HandleExtensionAlertClosed() { |
1795 extension_error_ui_.reset(); | 1797 extension_error_ui_.reset(); |
1796 } | 1798 } |
1797 | 1799 |
1798 void ExtensionService::HandleExtensionAlertAccept() { | 1800 void ExtensionService::HandleExtensionAlertAccept() { |
1799 const ExtensionIdSet *extension_ids = | 1801 const ExtensionIdSet* extension_ids = |
1800 extension_error_ui_->get_external_extension_ids(); | 1802 extension_error_ui_->get_blacklisted_extension_ids(); |
1801 for (ExtensionIdSet::const_iterator iter = extension_ids->begin(); | |
1802 iter != extension_ids->end(); ++iter) { | |
1803 AcknowledgeExternalExtension(*iter); | |
1804 } | |
1805 extension_ids = extension_error_ui_->get_blacklisted_extension_ids(); | |
1806 for (ExtensionIdSet::const_iterator iter = extension_ids->begin(); | 1803 for (ExtensionIdSet::const_iterator iter = extension_ids->begin(); |
1807 iter != extension_ids->end(); ++iter) { | 1804 iter != extension_ids->end(); ++iter) { |
1808 extension_prefs_->AcknowledgeBlacklistedExtension(*iter); | 1805 extension_prefs_->AcknowledgeBlacklistedExtension(*iter); |
1809 } | 1806 } |
1810 extension_ids = extension_error_ui_->get_orphaned_extension_ids(); | 1807 extension_ids = extension_error_ui_->get_orphaned_extension_ids(); |
1811 for (ExtensionIdSet::const_iterator iter = extension_ids->begin(); | 1808 for (ExtensionIdSet::const_iterator iter = extension_ids->begin(); |
1812 iter != extension_ids->end(); ++iter) { | 1809 iter != extension_ids->end(); ++iter) { |
1813 extension_prefs_->AcknowledgeOrphanedExtension(*iter); | 1810 extension_prefs_->AcknowledgeOrphanedExtension(*iter); |
1814 } | 1811 } |
1815 } | 1812 } |
1816 | 1813 |
1817 void ExtensionService::AcknowledgeExternalExtension(const std::string& id) { | 1814 void ExtensionService::AcknowledgeExternalExtension(const std::string& id) { |
1818 extension_prefs_->AcknowledgeExternalExtension(id); | 1815 extension_prefs_->AcknowledgeExternalExtension(id); |
| 1816 UpdateExternalExtensionAlert(); |
1819 } | 1817 } |
1820 | 1818 |
1821 void ExtensionService::HandleExtensionAlertDetails() { | 1819 void ExtensionService::HandleExtensionAlertDetails() { |
1822 extension_error_ui_->ShowExtensions(); | 1820 extension_error_ui_->ShowExtensions(); |
1823 } | 1821 } |
1824 | 1822 |
| 1823 void ExtensionService::UpdateExternalExtensionAlert() { |
| 1824 #if !defined(OS_CHROMEOS) |
| 1825 if (!extensions::FeatureSwitch::prompt_for_external_extensions()-> |
| 1826 IsEnabled()) |
| 1827 return; |
| 1828 |
| 1829 const Extension* extension = NULL; |
| 1830 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); |
| 1831 iter != disabled_extensions_.end(); ++iter) { |
| 1832 const Extension* e = *iter; |
| 1833 if (Extension::IsExternalLocation(e->location())) { |
| 1834 if (!e->is_hosted_app()) { |
| 1835 if (!extension_prefs_->IsExternalExtensionAcknowledged(e->id())) { |
| 1836 extension = e; |
| 1837 break; |
| 1838 } |
| 1839 } |
| 1840 } |
| 1841 } |
| 1842 |
| 1843 if (extension) { |
| 1844 if (extensions::AddExternalInstallError(this, extension)) { |
| 1845 if (extension_prefs_->IncrementAcknowledgePromptCount(extension->id()) >= |
| 1846 kMaxExtensionAcknowledgePromptCount) { |
| 1847 // This will be the last time we prompt for this extension. |
| 1848 extension_prefs_->AcknowledgeExternalExtension(extension->id()); |
| 1849 } |
| 1850 } |
| 1851 } else { |
| 1852 extensions::RemoveExternalInstallError(this); |
| 1853 } |
| 1854 #endif |
| 1855 } |
| 1856 |
1825 void ExtensionService::UnloadExtension( | 1857 void ExtensionService::UnloadExtension( |
1826 const std::string& extension_id, | 1858 const std::string& extension_id, |
1827 extension_misc::UnloadedExtensionReason reason) { | 1859 extension_misc::UnloadedExtensionReason reason) { |
1828 // Make sure the extension gets deleted after we return from this function. | 1860 // Make sure the extension gets deleted after we return from this function. |
1829 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 1861 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; |
1830 scoped_refptr<const Extension> extension( | 1862 scoped_refptr<const Extension> extension( |
1831 GetExtensionByIdInternal(extension_id, include_mask)); | 1863 GetExtensionByIdInternal(extension_id, include_mask)); |
1832 | 1864 |
1833 // This method can be called via PostTask, so the extension may have been | 1865 // This method can be called via PostTask, so the extension may have been |
1834 // unloaded by the time this runs. | 1866 // unloaded by the time this runs. |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 | 2178 |
2147 void ExtensionService::OnExtensionInstalled( | 2179 void ExtensionService::OnExtensionInstalled( |
2148 const Extension* extension, | 2180 const Extension* extension, |
2149 const syncer::StringOrdinal& page_ordinal, | 2181 const syncer::StringOrdinal& page_ordinal, |
2150 bool has_requirement_errors) { | 2182 bool has_requirement_errors) { |
2151 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2183 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
2152 | 2184 |
2153 // Ensure extension is deleted unless we transfer ownership. | 2185 // Ensure extension is deleted unless we transfer ownership. |
2154 scoped_refptr<const Extension> scoped_extension(extension); | 2186 scoped_refptr<const Extension> scoped_extension(extension); |
2155 const std::string& id = extension->id(); | 2187 const std::string& id = extension->id(); |
2156 // Extensions installed by policy can't be disabled. So even if a previous | 2188 bool initial_enable = ShouldEnableOnInstall(extension); |
2157 // installation disabled the extension, make sure it is now enabled. | |
2158 bool initial_enable = | |
2159 !extension_prefs_->IsExtensionDisabled(id) || | |
2160 system_->management_policy()->MustRemainEnabled(extension, NULL); | |
2161 const extensions::PendingExtensionInfo* pending_extension_info = NULL; | 2189 const extensions::PendingExtensionInfo* pending_extension_info = NULL; |
2162 if ((pending_extension_info = pending_extension_manager()->GetById(id))) { | 2190 if ((pending_extension_info = pending_extension_manager()->GetById(id))) { |
2163 if (!pending_extension_info->ShouldAllowInstall(*extension)) { | 2191 if (!pending_extension_info->ShouldAllowInstall(*extension)) { |
2164 pending_extension_manager()->Remove(id); | 2192 pending_extension_manager()->Remove(id); |
2165 | 2193 |
2166 LOG(WARNING) << "ShouldAllowInstall() returned false for " | 2194 LOG(WARNING) << "ShouldAllowInstall() returned false for " |
2167 << id << " of type " << extension->GetType() | 2195 << id << " of type " << extension->GetType() |
2168 << " and update URL " << extension->update_url().spec() | 2196 << " and update URL " << extension->update_url().spec() |
2169 << "; not installing"; | 2197 << "; not installing"; |
2170 | 2198 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2234 extension_prefs_->SetAllowFileAccess(id, true); | 2262 extension_prefs_->SetAllowFileAccess(id, true); |
2235 } | 2263 } |
2236 | 2264 |
2237 content::NotificationService::current()->Notify( | 2265 content::NotificationService::current()->Notify( |
2238 chrome::NOTIFICATION_EXTENSION_INSTALLED, | 2266 chrome::NOTIFICATION_EXTENSION_INSTALLED, |
2239 content::Source<Profile>(profile_), | 2267 content::Source<Profile>(profile_), |
2240 content::Details<const Extension>(extension)); | 2268 content::Details<const Extension>(extension)); |
2241 | 2269 |
2242 // Transfer ownership of |extension| to AddExtension. | 2270 // Transfer ownership of |extension| to AddExtension. |
2243 AddExtension(scoped_extension); | 2271 AddExtension(scoped_extension); |
| 2272 |
| 2273 // If this is a new external extension that was disabled, alert the user |
| 2274 // so he can reenable it. |
| 2275 if (Extension::IsExternalLocation(extension->location()) && !initial_enable) |
| 2276 UpdateExternalExtensionAlert(); |
2244 } | 2277 } |
2245 | 2278 |
2246 const Extension* ExtensionService::GetExtensionByIdInternal( | 2279 const Extension* ExtensionService::GetExtensionByIdInternal( |
2247 const std::string& id, int include_mask) const { | 2280 const std::string& id, int include_mask) const { |
2248 std::string lowercase_id = StringToLowerASCII(id); | 2281 std::string lowercase_id = StringToLowerASCII(id); |
2249 if (include_mask & INCLUDE_ENABLED) { | 2282 if (include_mask & INCLUDE_ENABLED) { |
2250 const Extension* extension = extensions_.GetByID(lowercase_id); | 2283 const Extension* extension = extensions_.GetByID(lowercase_id); |
2251 if (extension) | 2284 if (extension) |
2252 return extension; | 2285 return extension; |
2253 } | 2286 } |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2676 extension_host->extension(), | 2709 extension_host->extension(), |
2677 NULL, FilePath()); | 2710 NULL, FilePath()); |
2678 #endif | 2711 #endif |
2679 } | 2712 } |
2680 | 2713 |
2681 void ExtensionService::InspectExtensionHost( | 2714 void ExtensionService::InspectExtensionHost( |
2682 extensions::ExtensionHost* host) { | 2715 extensions::ExtensionHost* host) { |
2683 if (host) | 2716 if (host) |
2684 DevToolsWindow::OpenDevToolsWindow(host->render_view_host()); | 2717 DevToolsWindow::OpenDevToolsWindow(host->render_view_host()); |
2685 } | 2718 } |
| 2719 |
| 2720 bool ExtensionService::ShouldEnableOnInstall(const Extension* extension) { |
| 2721 // Extensions installed by policy can't be disabled. So even if a previous |
| 2722 // installation disabled the extension, make sure it is now enabled. |
| 2723 if (system_->management_policy()->MustRemainEnabled(extension, NULL)) |
| 2724 return true; |
| 2725 |
| 2726 if (extension_prefs_->IsExtensionDisabled(extension->id())) |
| 2727 return false; |
| 2728 |
| 2729 #if !defined(OS_CHROMEOS) |
| 2730 if (extensions::FeatureSwitch::prompt_for_external_extensions()-> |
| 2731 IsEnabled()) { |
| 2732 // External extensions are initially disabled. We prompt the user before |
| 2733 // enabling them. |
| 2734 if (Extension::IsExternalLocation(extension->location()) && |
| 2735 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { |
| 2736 return false; |
| 2737 } |
| 2738 } |
| 2739 #endif |
| 2740 |
| 2741 return true; |
| 2742 } |
OLD | NEW |