Chromium Code Reviews| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 #include "chrome/browser/themes/theme_service_factory.h" | 69 #include "chrome/browser/themes/theme_service_factory.h" |
| 70 #include "chrome/browser/ui/webui/favicon_source.h" | 70 #include "chrome/browser/ui/webui/favicon_source.h" |
| 71 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" | 71 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h" |
| 72 #include "chrome/browser/ui/webui/theme_source.h" | 72 #include "chrome/browser/ui/webui/theme_source.h" |
| 73 #include "chrome/common/child_process_logging.h" | 73 #include "chrome/common/child_process_logging.h" |
| 74 #include "chrome/common/chrome_notification_types.h" | 74 #include "chrome/common/chrome_notification_types.h" |
| 75 #include "chrome/common/chrome_switches.h" | 75 #include "chrome/common/chrome_switches.h" |
| 76 #include "chrome/common/chrome_version_info.h" | 76 #include "chrome/common/chrome_version_info.h" |
| 77 #include "chrome/common/extensions/background_info.h" | 77 #include "chrome/common/extensions/background_info.h" |
| 78 #include "chrome/common/extensions/extension.h" | 78 #include "chrome/common/extensions/extension.h" |
| 79 #include "chrome/common/extensions/extension_constants.h" | |
| 79 #include "chrome/common/extensions/extension_file_util.h" | 80 #include "chrome/common/extensions/extension_file_util.h" |
| 80 #include "chrome/common/extensions/extension_manifest_constants.h" | 81 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 81 #include "chrome/common/extensions/extension_messages.h" | 82 #include "chrome/common/extensions/extension_messages.h" |
| 82 #include "chrome/common/extensions/feature_switch.h" | 83 #include "chrome/common/extensions/feature_switch.h" |
| 83 #include "chrome/common/extensions/features/feature.h" | 84 #include "chrome/common/extensions/features/feature.h" |
| 84 #include "chrome/common/extensions/incognito_handler.h" | 85 #include "chrome/common/extensions/incognito_handler.h" |
| 85 #include "chrome/common/extensions/manifest.h" | 86 #include "chrome/common/extensions/manifest.h" |
| 86 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" | 87 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" |
| 87 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | 88 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" |
| 89 #include "chrome/common/extensions/manifest_handlers/shared_module_info.h" | |
| 88 #include "chrome/common/extensions/manifest_url_handler.h" | 90 #include "chrome/common/extensions/manifest_url_handler.h" |
| 89 #include "chrome/common/extensions/permissions/permissions_data.h" | 91 #include "chrome/common/extensions/permissions/permissions_data.h" |
| 90 #include "chrome/common/extensions/sync_helper.h" | 92 #include "chrome/common/extensions/sync_helper.h" |
| 91 #include "chrome/common/pref_names.h" | 93 #include "chrome/common/pref_names.h" |
| 92 #include "chrome/common/startup_metric_utils.h" | 94 #include "chrome/common/startup_metric_utils.h" |
| 93 #include "chrome/common/url_constants.h" | 95 #include "chrome/common/url_constants.h" |
| 94 #include "content/public/browser/browser_thread.h" | 96 #include "content/public/browser/browser_thread.h" |
| 95 #include "content/public/browser/devtools_agent_host.h" | 97 #include "content/public/browser/devtools_agent_host.h" |
| 96 #include "content/public/browser/notification_service.h" | 98 #include "content/public/browser/notification_service.h" |
| 97 #include "content/public/browser/notification_types.h" | 99 #include "content/public/browser/notification_types.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 120 using content::DevToolsAgentHost; | 122 using content::DevToolsAgentHost; |
| 121 using extensions::CrxInstaller; | 123 using extensions::CrxInstaller; |
| 122 using extensions::Extension; | 124 using extensions::Extension; |
| 123 using extensions::ExtensionIdSet; | 125 using extensions::ExtensionIdSet; |
| 124 using extensions::ExtensionInfo; | 126 using extensions::ExtensionInfo; |
| 125 using extensions::FeatureSwitch; | 127 using extensions::FeatureSwitch; |
| 126 using extensions::Manifest; | 128 using extensions::Manifest; |
| 127 using extensions::PermissionMessage; | 129 using extensions::PermissionMessage; |
| 128 using extensions::PermissionMessages; | 130 using extensions::PermissionMessages; |
| 129 using extensions::PermissionSet; | 131 using extensions::PermissionSet; |
| 132 using extensions::SharedModuleInfo; | |
| 130 using extensions::UnloadedExtensionInfo; | 133 using extensions::UnloadedExtensionInfo; |
| 131 | 134 |
| 132 namespace errors = extension_manifest_errors; | 135 namespace errors = extension_manifest_errors; |
| 133 | 136 |
| 134 namespace { | 137 namespace { |
| 135 | 138 |
| 136 // Histogram values for logging events related to externally installed | 139 // Histogram values for logging events related to externally installed |
| 137 // extensions. | 140 // extensions. |
| 138 enum ExternalExtensionEvent { | 141 enum ExternalExtensionEvent { |
| 139 EXTERNAL_EXTENSION_INSTALLED = 0, | 142 EXTERNAL_EXTENSION_INSTALLED = 0, |
| 140 EXTERNAL_EXTENSION_IGNORED, | 143 EXTERNAL_EXTENSION_IGNORED, |
| 141 EXTERNAL_EXTENSION_REENABLED, | 144 EXTERNAL_EXTENSION_REENABLED, |
| 142 EXTERNAL_EXTENSION_UNINSTALLED, | 145 EXTERNAL_EXTENSION_UNINSTALLED, |
| 143 EXTERNAL_EXTENSION_BUCKET_BOUNDARY, | 146 EXTERNAL_EXTENSION_BUCKET_BOUNDARY, |
| 144 }; | 147 }; |
| 145 | 148 |
| 146 // Prompt the user this many times before considering an extension acknowledged. | 149 // Prompt the user this many times before considering an extension acknowledged. |
| 147 static const int kMaxExtensionAcknowledgePromptCount = 3; | 150 static const int kMaxExtensionAcknowledgePromptCount = 3; |
| 148 | 151 |
| 149 // Wait this many seconds after an extensions becomes idle before updating it. | 152 // Wait this many seconds after an extensions becomes idle before updating it. |
| 150 static const int kUpdateIdleDelay = 5; | 153 static const int kUpdateIdleDelay = 5; |
| 151 | 154 |
| 152 // Wait this many seconds before trying to garbage collect extensions again. | 155 // Wait this many seconds before trying to garbage collect extensions again. |
| 153 static const int kGarbageCollectRetryDelay = 30; | 156 static const int kGarbageCollectRetryDelay = 30; |
| 154 | 157 |
| 158 static bool IsSharedModule(const Extension* extension) { | |
| 159 return SharedModuleInfo::IsSharedModule(extension); | |
| 160 } | |
| 161 | |
| 155 } // namespace | 162 } // namespace |
| 156 | 163 |
| 157 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData() | 164 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData() |
| 158 : background_page_ready(false), | 165 : background_page_ready(false), |
| 159 being_upgraded(false), | 166 being_upgraded(false), |
| 160 has_used_webrequest(false) { | 167 has_used_webrequest(false) { |
| 161 } | 168 } |
| 162 | 169 |
| 163 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { | 170 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { |
| 164 } | 171 } |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 | 552 |
| 546 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 553 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| 547 if (cmd_line->HasSwitch(switches::kInstallFromWebstore) || | 554 if (cmd_line->HasSwitch(switches::kInstallFromWebstore) || |
| 548 cmd_line->HasSwitch(switches::kLimitedInstallFromWebstore)) { | 555 cmd_line->HasSwitch(switches::kLimitedInstallFromWebstore)) { |
| 549 // The sole purpose of this launch is to install a new extension from CWS | 556 // The sole purpose of this launch is to install a new extension from CWS |
| 550 // and immediately terminate: loading already installed extensions is | 557 // and immediately terminate: loading already installed extensions is |
| 551 // unnecessary and may interfere with the inline install dialog (e.g. if an | 558 // unnecessary and may interfere with the inline install dialog (e.g. if an |
| 552 // extension listens to onStartup and opens a window). | 559 // extension listens to onStartup and opens a window). |
| 553 SetReadyAndNotifyListeners(); | 560 SetReadyAndNotifyListeners(); |
| 554 } else { | 561 } else { |
| 555 // TODO(mek): It might be cleaner to do the FinishDelayedInstallInfo stuff | |
| 556 // here instead of in installedloader. | |
| 557 if (g_browser_process->profile_manager() && | 562 if (g_browser_process->profile_manager() && |
| 558 g_browser_process->profile_manager()->will_import()) { | 563 g_browser_process->profile_manager()->will_import()) { |
| 559 // Do not load any component extensions, since they may conflict with the | 564 // Do not load any component extensions, since they may conflict with the |
| 560 // import process. | 565 // import process. |
| 561 | 566 |
| 562 extensions::InstalledLoader(this).LoadAllExtensions(); | 567 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 563 SetReadyAndNotifyListeners(); | 568 SetReadyAndNotifyListeners(); |
| 564 RegisterForImportFinished(); | 569 RegisterForImportFinished(); |
| 565 } else { | 570 } else { |
| 566 // In this case, LoadAllExtensions() calls OnLoadedInstalledExtensions(). | 571 // In this case, LoadAllExtensions() calls OnLoadedInstalledExtensions(). |
| 567 component_loader_->LoadAll(); | 572 component_loader_->LoadAll(); |
| 568 extensions::InstalledLoader(this).LoadAllExtensions(); | 573 extensions::InstalledLoader(this).LoadAllExtensions(); |
| 569 SetReadyAndNotifyListeners(); | 574 SetReadyAndNotifyListeners(); |
| 570 | 575 |
| 571 // TODO(erikkay) this should probably be deferred to a future point | 576 // TODO(erikkay) this should probably be deferred to a future point |
| 572 // rather than running immediately at startup. | 577 // rather than running immediately at startup. |
| 573 CheckForExternalUpdates(); | 578 CheckForExternalUpdates(); |
| 574 | 579 |
| 575 // TODO(erikkay) this should probably be deferred as well. | 580 // TODO(erikkay) this should probably be deferred as well. |
| 576 GarbageCollectExtensions(); | 581 GarbageCollectExtensions(); |
| 577 } | 582 } |
| 578 | 583 |
| 584 // Finish install (if possible) of extensions that were still delayed while | |
| 585 // the browser was shut down. | |
| 586 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info( | |
| 587 extension_prefs_->GetAllDelayedInstallInfo()); | |
| 588 for (size_t i = 0; i < delayed_info->size(); ++i) { | |
| 589 ExtensionInfo* info = delayed_info->at(i).get(); | |
| 590 scoped_refptr<const Extension> extension(NULL); | |
| 591 if (info->extension_manifest) { | |
| 592 std::string error; | |
| 593 extension = Extension::Create( | |
| 594 info->extension_path, | |
| 595 info->extension_location, | |
| 596 *info->extension_manifest, | |
| 597 extension_prefs_->GetDelayedInstallCreationFlags( | |
| 598 info->extension_id), | |
| 599 &error); | |
| 600 if (extension.get()) | |
| 601 delayed_installs_.Insert(extension); | |
| 602 } | |
| 603 } | |
| 604 MaybeFinishDelayedInstallations(); | |
| 605 scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info2( | |
| 606 extension_prefs_->GetAllDelayedInstallInfo()); | |
| 607 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad", | |
| 608 delayed_info2->size() - delayed_info->size()); | |
| 609 | |
| 579 if (extension_prefs_->NeedsStorageGarbageCollection()) { | 610 if (extension_prefs_->NeedsStorageGarbageCollection()) { |
| 580 GarbageCollectIsolatedStorage(); | 611 GarbageCollectIsolatedStorage(); |
| 581 extension_prefs_->SetNeedsStorageGarbageCollection(false); | 612 extension_prefs_->SetNeedsStorageGarbageCollection(false); |
| 582 } | 613 } |
| 583 } | 614 } |
| 584 } | 615 } |
| 585 | 616 |
| 586 bool ExtensionService::UpdateExtension(const std::string& id, | 617 bool ExtensionService::UpdateExtension(const std::string& id, |
| 587 const base::FilePath& extension_path, | 618 const base::FilePath& extension_path, |
| 588 const GURL& download_url, | 619 const GURL& download_url, |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 orphaned_dev_tools_[extension_id] = devtools_cookie; | 725 orphaned_dev_tools_[extension_id] = devtools_cookie; |
| 695 } | 726 } |
| 696 | 727 |
| 697 path = current_extension->path(); | 728 path = current_extension->path(); |
| 698 DisableExtension(extension_id, Extension::DISABLE_RELOAD); | 729 DisableExtension(extension_id, Extension::DISABLE_RELOAD); |
| 699 reloading_extensions_.insert(extension_id); | 730 reloading_extensions_.insert(extension_id); |
| 700 } else { | 731 } else { |
| 701 path = unloaded_extension_paths_[extension_id]; | 732 path = unloaded_extension_paths_[extension_id]; |
| 702 } | 733 } |
| 703 | 734 |
| 704 if (delayed_updates_for_idle_.Contains(extension_id)) { | 735 if (delayed_installs_.Contains(extension_id)) { |
| 705 FinishDelayedInstallation(extension_id); | 736 FinishDelayedInstallation(extension_id); |
| 706 return; | 737 return; |
| 707 } | 738 } |
| 708 | 739 |
| 709 // If we're reloading a component extension, use the component extension | 740 // If we're reloading a component extension, use the component extension |
| 710 // loader's reloader. | 741 // loader's reloader. |
| 711 if (component_loader_->Exists(extension_id)) { | 742 if (component_loader_->Exists(extension_id)) { |
| 712 component_loader_->Reload(extension_id); | 743 component_loader_->Reload(extension_id); |
| 713 return; | 744 return; |
| 714 } | 745 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 822 content::Details<const Extension>(extension.get())); | 853 content::Details<const Extension>(extension.get())); |
| 823 | 854 |
| 824 if (app_sync_bundle_.HasExtensionId(extension_id) && | 855 if (app_sync_bundle_.HasExtensionId(extension_id) && |
| 825 sync_change.sync_data().GetDataType() == syncer::APPS) { | 856 sync_change.sync_data().GetDataType() == syncer::APPS) { |
| 826 app_sync_bundle_.ProcessDeletion(extension_id, sync_change); | 857 app_sync_bundle_.ProcessDeletion(extension_id, sync_change); |
| 827 } else if (extension_sync_bundle_.HasExtensionId(extension_id) && | 858 } else if (extension_sync_bundle_.HasExtensionId(extension_id) && |
| 828 sync_change.sync_data().GetDataType() == syncer::EXTENSIONS) { | 859 sync_change.sync_data().GetDataType() == syncer::EXTENSIONS) { |
| 829 extension_sync_bundle_.ProcessDeletion(extension_id, sync_change); | 860 extension_sync_bundle_.ProcessDeletion(extension_id, sync_change); |
| 830 } | 861 } |
| 831 | 862 |
| 832 delayed_updates_for_idle_.Remove(extension_id); | |
| 833 delayed_installs_.Remove(extension_id); | 863 delayed_installs_.Remove(extension_id); |
| 834 | 864 |
| 865 PruneSharedModulesOnUninstall(extension); | |
| 866 | |
| 835 // Track the uninstallation. | 867 // Track the uninstallation. |
| 836 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); | 868 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); |
| 837 | 869 |
| 838 return true; | 870 return true; |
| 839 } | 871 } |
| 840 | 872 |
| 841 bool ExtensionService::IsExtensionEnabled( | 873 bool ExtensionService::IsExtensionEnabled( |
| 842 const std::string& extension_id) const { | 874 const std::string& extension_id) const { |
| 843 if (extensions_.Contains(extension_id) || | 875 if (extensions_.Contains(extension_id) || |
| 844 terminated_extensions_.Contains(extension_id)) { | 876 terminated_extensions_.Contains(extension_id)) { |
| (...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2169 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 2201 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
| 2170 iter != extensions_.end(); ++iter) { | 2202 iter != extensions_.end(); ++iter) { |
| 2171 const Extension* extension = *iter; | 2203 const Extension* extension = *iter; |
| 2172 if (!extension->is_theme() && extension->location() != Manifest::COMPONENT) | 2204 if (!extension->is_theme() && extension->location() != Manifest::COMPONENT) |
| 2173 extension_ids.insert(extension->id()); | 2205 extension_ids.insert(extension->id()); |
| 2174 } | 2206 } |
| 2175 | 2207 |
| 2176 child_process_logging::SetActiveExtensions(extension_ids); | 2208 child_process_logging::SetActiveExtensions(extension_ids); |
| 2177 } | 2209 } |
| 2178 | 2210 |
| 2211 bool ExtensionService::CheckImports(const Extension* extension, | |
| 2212 bool* unrecoverable) { | |
| 2213 bool import_failed = false; | |
| 2214 // TODO(elijahtaylor): Message the user if there is a failure that is | |
| 2215 // unrecoverable. | |
|
asargent_no_longer_on_chrome
2013/06/13 05:47:16
Maybe add "CHECK(unrecoverable != NULL);" here?
elijahtaylor1
2013/06/13 23:32:09
removed
| |
| 2216 *unrecoverable = false; | |
| 2217 if (SharedModuleInfo::ImportsModules(extension)) { | |
| 2218 const std::vector<SharedModuleInfo::ImportInfo>& imports = | |
| 2219 SharedModuleInfo::GetImports(extension); | |
| 2220 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i; | |
| 2221 for (i = imports.begin(); i != imports.end(); ++i) { | |
| 2222 Version version_required(i->minimum_version); | |
| 2223 const Extension* imported_module = | |
| 2224 GetExtensionById(i->extension_id, true); | |
| 2225 if (!imported_module) { | |
| 2226 import_failed = true; | |
| 2227 if (extension->from_webstore()) { | |
| 2228 if (pending_extension_manager()->AddFromExtensionImport( | |
| 2229 i->extension_id, | |
| 2230 extension_urls::GetWebstoreUpdateUrl(), | |
| 2231 IsSharedModule)) { | |
| 2232 CheckForUpdatesSoon(); | |
| 2233 } | |
| 2234 } else { | |
| 2235 *unrecoverable = true; | |
| 2236 } | |
| 2237 } else if (!SharedModuleInfo::IsSharedModule(imported_module)) { | |
| 2238 import_failed = true; | |
| 2239 *unrecoverable = true; | |
| 2240 } else if (version_required.IsValid() && | |
| 2241 imported_module->version()->CompareTo(version_required) < 0) { | |
| 2242 import_failed = true; | |
| 2243 if (imported_module->from_webstore()) { | |
| 2244 CheckForUpdatesSoon(); | |
| 2245 } else { | |
| 2246 *unrecoverable = true; | |
| 2247 } | |
| 2248 } | |
| 2249 } | |
| 2250 } | |
| 2251 return !import_failed; | |
| 2252 } | |
| 2253 | |
| 2254 scoped_ptr<const ExtensionSet> | |
| 2255 ExtensionService::GetSharedModuleImporters(const Extension* extension) { | |
| 2256 scoped_ptr<ExtensionSet> importers(new ExtensionSet()); | |
| 2257 scoped_ptr<ExtensionSet> set_to_check(new ExtensionSet()); | |
| 2258 if (SharedModuleInfo::IsSharedModule(extension)) { | |
| 2259 set_to_check->InsertAll(disabled_extensions_); | |
| 2260 set_to_check->InsertAll(delayed_installs_); | |
| 2261 set_to_check->InsertAll(extensions_); | |
| 2262 for (ExtensionSet::const_iterator iter = set_to_check->begin(); | |
| 2263 iter != set_to_check->end(); ++iter) { | |
| 2264 if (SharedModuleInfo::ImportsExtensionById(*iter, extension->id())) { | |
| 2265 importers->Insert(*iter); | |
| 2266 } | |
| 2267 } | |
| 2268 } | |
| 2269 return importers.PassAs<const ExtensionSet>(); | |
| 2270 } | |
| 2271 | |
| 2272 void ExtensionService::PruneSharedModulesOnUninstall( | |
| 2273 const Extension* extension) { | |
| 2274 if (SharedModuleInfo::ImportsModules(extension)) { | |
| 2275 const std::vector<SharedModuleInfo::ImportInfo>& imports = | |
| 2276 SharedModuleInfo::GetImports(extension); | |
| 2277 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i; | |
| 2278 for (i = imports.begin(); i != imports.end(); ++i) { | |
| 2279 const Extension* imported_module = | |
| 2280 GetExtensionById(i->extension_id, true); | |
| 2281 if (imported_module && imported_module->from_webstore()) { | |
| 2282 scoped_ptr<const ExtensionSet> importers = | |
| 2283 GetSharedModuleImporters(imported_module); | |
| 2284 if (importers->size() == 0) { | |
| 2285 UninstallExtension(i->extension_id, false, NULL); | |
| 2286 } | |
| 2287 } | |
| 2288 } | |
| 2289 } | |
| 2290 } | |
| 2291 | |
| 2179 void ExtensionService::OnExtensionInstalled( | 2292 void ExtensionService::OnExtensionInstalled( |
| 2180 const Extension* extension, | 2293 const Extension* extension, |
| 2181 const syncer::StringOrdinal& page_ordinal, | 2294 const syncer::StringOrdinal& page_ordinal, |
| 2182 bool has_requirement_errors, | 2295 bool has_requirement_errors, |
| 2183 bool wait_for_idle) { | 2296 bool wait_for_idle) { |
| 2184 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2297 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2185 | 2298 |
| 2186 const std::string& id = extension->id(); | 2299 const std::string& id = extension->id(); |
| 2187 bool initial_enable = ShouldEnableOnInstall(extension); | 2300 bool initial_enable = ShouldEnableOnInstall(extension); |
| 2188 const extensions::PendingExtensionInfo* pending_extension_info = NULL; | 2301 const extensions::PendingExtensionInfo* pending_extension_info = NULL; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2251 } | 2364 } |
| 2252 | 2365 |
| 2253 // Certain extension locations are specific enough that we can | 2366 // Certain extension locations are specific enough that we can |
| 2254 // auto-acknowledge any extension that came from one of them. | 2367 // auto-acknowledge any extension that came from one of them. |
| 2255 if (extension->location() == Manifest::EXTERNAL_POLICY_DOWNLOAD) | 2368 if (extension->location() == Manifest::EXTERNAL_POLICY_DOWNLOAD) |
| 2256 AcknowledgeExternalExtension(extension->id()); | 2369 AcknowledgeExternalExtension(extension->id()); |
| 2257 const Extension::State initial_state = | 2370 const Extension::State initial_state = |
| 2258 initial_enable ? Extension::ENABLED : Extension::DISABLED; | 2371 initial_enable ? Extension::ENABLED : Extension::DISABLED; |
| 2259 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { | 2372 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { |
| 2260 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, | 2373 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, |
| 2261 page_ordinal); | 2374 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, page_ordinal); |
| 2262 | 2375 |
| 2263 // Transfer ownership of |extension|. | 2376 // Transfer ownership of |extension|. |
| 2264 delayed_updates_for_idle_.Insert(extension); | 2377 delayed_installs_.Insert(extension); |
| 2265 | 2378 |
| 2266 // Notify extension of available update. | 2379 // Notify extension of available update. |
| 2267 extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent( | 2380 extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent( |
| 2268 profile_, id, extension->manifest()->value()); | 2381 profile_, id, extension->manifest()->value()); |
| 2269 | 2382 |
| 2270 // Notify observers that app update is available. | 2383 // Notify observers that app update is available. |
| 2271 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, | 2384 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, |
| 2272 OnAppUpdateAvailable(extension->id())); | 2385 OnAppUpdateAvailable(extension->id())); |
| 2273 return; | 2386 return; |
| 2274 } | 2387 } |
| 2275 | 2388 |
| 2389 bool unrecoverable_import_error; | |
|
asargent_no_longer_on_chrome
2013/06/13 05:47:16
consider initializing (otherwise you might get a c
elijahtaylor1
2013/06/13 23:32:09
removed
| |
| 2276 if (installs_delayed()) { | 2390 if (installs_delayed()) { |
| 2277 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, | 2391 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, |
| 2278 page_ordinal); | 2392 extensions::ExtensionPrefs::DELAY_REASON_GLOBAL, page_ordinal); |
| 2279 delayed_installs_.Insert(extension); | 2393 delayed_installs_.Insert(extension); |
| 2394 } else if (!CheckImports(extension, &unrecoverable_import_error)) { | |
| 2395 if (!unrecoverable_import_error) { | |
| 2396 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, | |
| 2397 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS, | |
| 2398 page_ordinal); | |
| 2399 delayed_installs_.Insert(extension); | |
| 2400 } | |
| 2280 } else { | 2401 } else { |
| 2281 AddNewOrUpdatedExtension(extension, initial_state, page_ordinal); | 2402 AddNewOrUpdatedExtension(extension, initial_state, page_ordinal); |
| 2282 } | 2403 } |
| 2283 } | 2404 } |
| 2284 | 2405 |
| 2285 void ExtensionService::AddNewOrUpdatedExtension( | 2406 void ExtensionService::AddNewOrUpdatedExtension( |
| 2286 const Extension* extension, | 2407 const Extension* extension, |
| 2287 Extension::State initial_state, | 2408 Extension::State initial_state, |
| 2288 const syncer::StringOrdinal& page_ordinal) { | 2409 const syncer::StringOrdinal& page_ordinal) { |
| 2289 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2410 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2290 | 2411 |
| 2291 extension_prefs_->OnExtensionInstalled( | 2412 extension_prefs_->OnExtensionInstalled( |
| 2292 extension, | 2413 extension, |
| 2293 initial_state, | 2414 initial_state, |
| 2294 page_ordinal); | 2415 page_ordinal); |
| 2295 | 2416 |
| 2296 FinishInstallation(extension); | 2417 FinishInstallation(extension); |
| 2297 } | 2418 } |
| 2298 | 2419 |
| 2299 void ExtensionService::MaybeFinishDelayedInstallation( | 2420 void ExtensionService::MaybeFinishDelayedInstallation( |
| 2300 const std::string& extension_id) { | 2421 const std::string& extension_id) { |
| 2301 // Check if the extension already got updated. | 2422 // Check if the extension already got installed. |
| 2302 if (!delayed_updates_for_idle_.Contains(extension_id)) | 2423 if (!delayed_installs_.Contains(extension_id)) |
| 2303 return; | 2424 return; |
| 2425 extensions::ExtensionPrefs::DelayReason reason = | |
| 2426 extension_prefs_->GetDelayedInstallReason(extension_id); | |
| 2427 | |
| 2304 // Check if the extension is idle. | 2428 // Check if the extension is idle. |
| 2305 if (!IsExtensionIdle(extension_id)) | 2429 if (reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE && |
| 2430 !IsExtensionIdle(extension_id)) | |
| 2306 return; | 2431 return; |
| 2307 | 2432 |
| 2433 const Extension* extension = delayed_installs_.GetByID(extension_id); | |
| 2434 bool unrecoverable_import_error; | |
| 2435 if (reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS && | |
| 2436 !CheckImports(extension, &unrecoverable_import_error)) { | |
| 2437 if (unrecoverable_import_error) { | |
| 2438 delayed_installs_.Remove(extension_id); | |
| 2439 // Make sure no version of the extension is actually installed, (i.e., | |
| 2440 // that this delayed install was not an update). | |
| 2441 CHECK(!extension_prefs_->GetInstalledExtensionInfo(extension_id).get()); | |
| 2442 extension_prefs_->DeleteExtensionPrefs(extension_id); | |
| 2443 } | |
| 2444 return; | |
| 2445 } | |
| 2446 | |
| 2308 FinishDelayedInstallation(extension_id); | 2447 FinishDelayedInstallation(extension_id); |
| 2309 } | 2448 } |
| 2310 | 2449 |
| 2311 void ExtensionService::FinishDelayedInstallation( | 2450 void ExtensionService::FinishDelayedInstallation( |
| 2312 const std::string& extension_id) { | 2451 const std::string& extension_id) { |
| 2313 scoped_refptr<const Extension> extension( | 2452 scoped_refptr<const Extension> extension( |
| 2314 GetPendingExtensionUpdate(extension_id)); | 2453 GetPendingExtensionUpdate(extension_id)); |
| 2315 CHECK(extension.get()); | 2454 CHECK(extension.get()); |
| 2316 delayed_updates_for_idle_.Remove(extension_id); | 2455 delayed_installs_.Remove(extension_id); |
| 2317 | 2456 |
| 2318 if (!extension_prefs_->FinishDelayedInstallInfo(extension_id)) | 2457 if (!extension_prefs_->FinishDelayedInstallInfo(extension_id)) |
| 2319 NOTREACHED(); | 2458 NOTREACHED(); |
| 2320 | 2459 |
| 2321 FinishInstallation(extension.get()); | 2460 FinishInstallation(extension.get()); |
| 2322 } | 2461 } |
| 2323 | 2462 |
| 2324 void ExtensionService::FinishInstallation(const Extension* extension) { | 2463 void ExtensionService::FinishInstallation(const Extension* extension) { |
| 2325 const extensions::Extension* existing_extension = | 2464 const extensions::Extension* existing_extension = |
| 2326 GetInstalledExtension(extension->id()); | 2465 GetInstalledExtension(extension->id()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2363 | 2502 |
| 2364 // If this is a new external extension that was disabled, alert the user | 2503 // If this is a new external extension that was disabled, alert the user |
| 2365 // so he can reenable it. We do this last so that it has already been | 2504 // so he can reenable it. We do this last so that it has already been |
| 2366 // added to our list of extensions. | 2505 // added to our list of extensions. |
| 2367 if (unacknowledged_external) { | 2506 if (unacknowledged_external) { |
| 2368 UpdateExternalExtensionAlert(); | 2507 UpdateExternalExtensionAlert(); |
| 2369 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", | 2508 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", |
| 2370 EXTERNAL_EXTENSION_INSTALLED, | 2509 EXTERNAL_EXTENSION_INSTALLED, |
| 2371 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 2510 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
| 2372 } | 2511 } |
| 2512 | |
| 2513 // Check extensions that may have been delayed only because this shared module | |
| 2514 // was not available. | |
| 2515 if (SharedModuleInfo::IsSharedModule(extension)) { | |
| 2516 MaybeFinishDelayedInstallations(); | |
| 2517 } | |
| 2373 } | 2518 } |
| 2374 | 2519 |
| 2375 const Extension* ExtensionService::GetPendingExtensionUpdate( | 2520 const Extension* ExtensionService::GetPendingExtensionUpdate( |
| 2376 const std::string& id) const { | 2521 const std::string& id) const { |
| 2377 return delayed_updates_for_idle_.GetByID(id); | 2522 return delayed_installs_.GetByID(id); |
| 2378 } | 2523 } |
| 2379 | 2524 |
| 2380 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { | 2525 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { |
| 2381 if (!terminated_extensions_.Contains(extension->id())) | 2526 if (!terminated_extensions_.Contains(extension->id())) |
| 2382 terminated_extensions_.Insert(make_scoped_refptr(extension)); | 2527 terminated_extensions_.Insert(make_scoped_refptr(extension)); |
| 2383 | 2528 |
| 2384 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); | 2529 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); |
| 2385 } | 2530 } |
| 2386 | 2531 |
| 2387 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { | 2532 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2605 break; | 2750 break; |
| 2606 } | 2751 } |
| 2607 case chrome::NOTIFICATION_IMPORT_FINISHED: { | 2752 case chrome::NOTIFICATION_IMPORT_FINISHED: { |
| 2608 InitAfterImport(); | 2753 InitAfterImport(); |
| 2609 break; | 2754 break; |
| 2610 } | 2755 } |
| 2611 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { | 2756 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { |
| 2612 extensions::ExtensionHost* host = | 2757 extensions::ExtensionHost* host = |
| 2613 content::Details<extensions::ExtensionHost>(details).ptr(); | 2758 content::Details<extensions::ExtensionHost>(details).ptr(); |
| 2614 std::string extension_id = host->extension_id(); | 2759 std::string extension_id = host->extension_id(); |
| 2615 if (delayed_updates_for_idle_.Contains(extension_id)) { | 2760 if (delayed_installs_.Contains(extension_id)) { |
| 2616 // We were waiting for this extension to become idle, it now might have, | 2761 // We were waiting for this extension to become idle, it now might have, |
| 2617 // so maybe finish installation. | 2762 // so maybe finish installation. |
| 2618 base::MessageLoop::current()->PostDelayedTask( | 2763 base::MessageLoop::current()->PostDelayedTask( |
| 2619 FROM_HERE, | 2764 FROM_HERE, |
| 2620 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation, | 2765 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation, |
| 2621 AsWeakPtr(), extension_id), | 2766 AsWeakPtr(), extension_id), |
| 2622 base::TimeDelta::FromSeconds(kUpdateIdleDelay)); | 2767 base::TimeDelta::FromSeconds(kUpdateIdleDelay)); |
| 2623 } | 2768 } |
| 2624 break; | 2769 break; |
| 2625 } | 2770 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2801 DCHECK(!installs_delayed()); | 2946 DCHECK(!installs_delayed()); |
| 2802 set_installs_delayed(true); | 2947 set_installs_delayed(true); |
| 2803 BrowserContext::GarbageCollectStoragePartitions( | 2948 BrowserContext::GarbageCollectStoragePartitions( |
| 2804 profile_, active_paths.Pass(), | 2949 profile_, active_paths.Pass(), |
| 2805 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished, | 2950 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished, |
| 2806 AsWeakPtr())); | 2951 AsWeakPtr())); |
| 2807 } | 2952 } |
| 2808 | 2953 |
| 2809 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { | 2954 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { |
| 2810 set_installs_delayed(false); | 2955 set_installs_delayed(false); |
| 2956 MaybeFinishDelayedInstallations(); | |
| 2957 } | |
| 2958 | |
| 2959 void ExtensionService::MaybeFinishDelayedInstallations() { | |
| 2960 std::vector<std::string> to_be_installed; | |
| 2811 for (ExtensionSet::const_iterator it = delayed_installs_.begin(); | 2961 for (ExtensionSet::const_iterator it = delayed_installs_.begin(); |
| 2812 it != delayed_installs_.end(); | 2962 it != delayed_installs_.end(); |
| 2813 ++it) { | 2963 ++it) { |
| 2814 FinishDelayedInstallation((*it)->id()); | 2964 to_be_installed.push_back((*it)->id()); |
| 2815 } | 2965 } |
| 2816 for (ExtensionSet::const_iterator it = delayed_updates_for_idle_.begin(); | 2966 for (std::vector<std::string>::const_iterator it = to_be_installed.begin(); |
| 2817 it != delayed_updates_for_idle_.end(); | 2967 it != to_be_installed.end(); |
| 2818 ++it) { | 2968 ++it) { |
| 2819 MaybeFinishDelayedInstallation((*it)->id()); | 2969 MaybeFinishDelayedInstallation(*it); |
| 2820 } | 2970 } |
| 2821 delayed_installs_.Clear(); | |
| 2822 } | 2971 } |
| 2823 | 2972 |
| 2824 void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() { | 2973 void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() { |
| 2825 extension_prefs_->SetNeedsStorageGarbageCollection(true); | 2974 extension_prefs_->SetNeedsStorageGarbageCollection(true); |
| 2826 } | 2975 } |
| 2827 | 2976 |
| 2828 void ExtensionService::OnBlacklistUpdated() { | 2977 void ExtensionService::OnBlacklistUpdated() { |
| 2829 blacklist_->GetBlacklistedIDs( | 2978 blacklist_->GetBlacklistedIDs( |
| 2830 GenerateInstalledExtensionsSet()->GetIDs(), | 2979 GenerateInstalledExtensionsSet()->GetIDs(), |
| 2831 base::Bind(&ExtensionService::ManageBlacklist, | 2980 base::Bind(&ExtensionService::ManageBlacklist, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2879 } | 3028 } |
| 2880 | 3029 |
| 2881 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { | 3030 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { |
| 2882 update_observers_.AddObserver(observer); | 3031 update_observers_.AddObserver(observer); |
| 2883 } | 3032 } |
| 2884 | 3033 |
| 2885 void ExtensionService::RemoveUpdateObserver( | 3034 void ExtensionService::RemoveUpdateObserver( |
| 2886 extensions::UpdateObserver* observer) { | 3035 extensions::UpdateObserver* observer) { |
| 2887 update_observers_.RemoveObserver(observer); | 3036 update_observers_.RemoveObserver(observer); |
| 2888 } | 3037 } |
| OLD | NEW |