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 |