Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: chrome/browser/extensions/extension_service.cc

Issue 14973007: Auto-install/uninstall shared module dependencies for extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update checkimports logic per feedback Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 import_failed = false;
2213 if (SharedModuleInfo::ImportsModules(extension)) {
2214 const std::vector<SharedModuleInfo::ImportInfo>& imports =
2215 SharedModuleInfo::GetImports(extension);
2216 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i;
2217 for (i = imports.begin(); i != imports.end(); ++i) {
2218 Version version_required(i->minimum_version);
2219 const Extension* imported_module =
2220 GetExtensionById(i->extension_id, true);
2221 if (!imported_module) {
2222 import_failed = true;
2223 if (extension->from_webstore()) {
2224 if (pending_extension_manager()->AddFromExtensionImport(
2225 i->extension_id,
2226 extension_urls::GetWebstoreUpdateUrl(),
2227 IsSharedModule)) {
2228 CheckForUpdatesSoon();
2229 }
2230 }
2231 } else if (!SharedModuleInfo::IsSharedModule(imported_module)) {
2232 import_failed = true;
2233 } else if (version_required.IsValid() &&
2234 imported_module->version()->CompareTo(version_required) < 0) {
2235 import_failed = true;
2236 if (imported_module->from_webstore())
2237 CheckForUpdatesSoon();
2238 }
2239 }
2240 }
2241 return !import_failed;
2242 }
2243
2244 scoped_ptr<const ExtensionSet>
2245 ExtensionService::GetSharedModuleImporters(const Extension* extension) {
2246 scoped_ptr<ExtensionSet> importers(new ExtensionSet());
2247 scoped_ptr<ExtensionSet> set_to_check(new ExtensionSet());
2248 if (SharedModuleInfo::IsSharedModule(extension)) {
2249 set_to_check->InsertAll(disabled_extensions_);
2250 set_to_check->InsertAll(delayed_installs_);
2251 set_to_check->InsertAll(extensions_);
2252 for (ExtensionSet::const_iterator iter = set_to_check->begin();
2253 iter != set_to_check->end(); ++iter) {
2254 if (SharedModuleInfo::ImportsExtensionById(*iter, extension->id())) {
2255 importers->Insert(*iter);
2256 }
2257 }
2258 }
2259 return importers.PassAs<const ExtensionSet>();
2260 }
2261
2262 void ExtensionService::PruneSharedModulesOnUninstall(
2263 const Extension* extension) {
2264 if (SharedModuleInfo::ImportsModules(extension)) {
2265 const std::vector<SharedModuleInfo::ImportInfo>& imports =
2266 SharedModuleInfo::GetImports(extension);
2267 std::vector<SharedModuleInfo::ImportInfo>::const_iterator i;
2268 for (i = imports.begin(); i != imports.end(); ++i) {
2269 const Extension* imported_module =
2270 GetExtensionById(i->extension_id, true);
2271 if (imported_module && imported_module->from_webstore()) {
2272 scoped_ptr<const ExtensionSet> importers =
2273 GetSharedModuleImporters(imported_module);
Matt Perry 2013/06/12 00:58:29 Seems like all you really need is HasSharedModuleI
elijahtaylor1 2013/06/12 23:53:23 I originally had that functionality only, but then
2274 if (importers->size() == 0) {
2275 UninstallExtension(i->extension_id, false, NULL);
2276 }
2277 }
2278 }
2279 }
2280 }
2281
2179 void ExtensionService::OnExtensionInstalled( 2282 void ExtensionService::OnExtensionInstalled(
2180 const Extension* extension, 2283 const Extension* extension,
2181 const syncer::StringOrdinal& page_ordinal, 2284 const syncer::StringOrdinal& page_ordinal,
2182 bool has_requirement_errors, 2285 bool has_requirement_errors,
2183 bool wait_for_idle) { 2286 bool wait_for_idle) {
2184 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2287 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2185 2288
2186 const std::string& id = extension->id(); 2289 const std::string& id = extension->id();
2187 bool initial_enable = ShouldEnableOnInstall(extension); 2290 bool initial_enable = ShouldEnableOnInstall(extension);
2188 const extensions::PendingExtensionInfo* pending_extension_info = NULL; 2291 const extensions::PendingExtensionInfo* pending_extension_info = NULL;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2251 } 2354 }
2252 2355
2253 // Certain extension locations are specific enough that we can 2356 // Certain extension locations are specific enough that we can
2254 // auto-acknowledge any extension that came from one of them. 2357 // auto-acknowledge any extension that came from one of them.
2255 if (extension->location() == Manifest::EXTERNAL_POLICY_DOWNLOAD) 2358 if (extension->location() == Manifest::EXTERNAL_POLICY_DOWNLOAD)
2256 AcknowledgeExternalExtension(extension->id()); 2359 AcknowledgeExternalExtension(extension->id());
2257 const Extension::State initial_state = 2360 const Extension::State initial_state =
2258 initial_enable ? Extension::ENABLED : Extension::DISABLED; 2361 initial_enable ? Extension::ENABLED : Extension::DISABLED;
2259 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) { 2362 if (ShouldDelayExtensionUpdate(id, wait_for_idle)) {
2260 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, 2363 extension_prefs_->SetDelayedInstallInfo(extension, initial_state,
2261 page_ordinal); 2364 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, page_ordinal);
2262 2365
2263 // Transfer ownership of |extension|. 2366 // Transfer ownership of |extension|.
2264 delayed_updates_for_idle_.Insert(extension); 2367 delayed_installs_.Insert(extension);
2265 2368
2266 // Notify extension of available update. 2369 // Notify extension of available update.
2267 extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent( 2370 extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent(
2268 profile_, id, extension->manifest()->value()); 2371 profile_, id, extension->manifest()->value());
2269 2372
2270 // Notify observers that app update is available. 2373 // Notify observers that app update is available.
2271 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, 2374 FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_,
2272 OnAppUpdateAvailable(extension->id())); 2375 OnAppUpdateAvailable(extension->id()));
2273 return; 2376 return;
2274 } 2377 }
2275 2378
2276 if (installs_delayed()) { 2379 if (installs_delayed()) {
2277 extension_prefs_->SetDelayedInstallInfo(extension, initial_state, 2380 extension_prefs_->SetDelayedInstallInfo(extension, initial_state,
2278 page_ordinal); 2381 extensions::ExtensionPrefs::DELAY_REASON_GLOBAL, page_ordinal);
2382 delayed_installs_.Insert(extension);
2383 } else if (!CheckImports(extension)) {
Matt Perry 2013/06/12 00:58:29 If this fails because the imported module is not a
elijahtaylor1 2013/06/12 23:53:23 As discussed offline, I've added a TODO for messag
2384 extension_prefs_->SetDelayedInstallInfo(extension, initial_state,
2385 extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
2386 page_ordinal);
2279 delayed_installs_.Insert(extension); 2387 delayed_installs_.Insert(extension);
2280 } else { 2388 } else {
2281 AddNewOrUpdatedExtension(extension, initial_state, page_ordinal); 2389 AddNewOrUpdatedExtension(extension, initial_state, page_ordinal);
2282 } 2390 }
2283 } 2391 }
2284 2392
2285 void ExtensionService::AddNewOrUpdatedExtension( 2393 void ExtensionService::AddNewOrUpdatedExtension(
2286 const Extension* extension, 2394 const Extension* extension,
2287 Extension::State initial_state, 2395 Extension::State initial_state,
2288 const syncer::StringOrdinal& page_ordinal) { 2396 const syncer::StringOrdinal& page_ordinal) {
2289 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2397 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2290 2398
2291 extension_prefs_->OnExtensionInstalled( 2399 extension_prefs_->OnExtensionInstalled(
2292 extension, 2400 extension,
2293 initial_state, 2401 initial_state,
2294 page_ordinal); 2402 page_ordinal);
2295 2403
2296 FinishInstallation(extension); 2404 FinishInstallation(extension);
2297 } 2405 }
2298 2406
2299 void ExtensionService::MaybeFinishDelayedInstallation( 2407 void ExtensionService::MaybeFinishDelayedInstallation(
2300 const std::string& extension_id) { 2408 const std::string& extension_id) {
2301 // Check if the extension already got updated. 2409 // Check if the extension already got installed.
2302 if (!delayed_updates_for_idle_.Contains(extension_id)) 2410 if (!delayed_installs_.Contains(extension_id))
2303 return; 2411 return;
2412 extensions::ExtensionPrefs::DelayReason reason =
2413 extension_prefs_->GetDelayedInstallReason(extension_id);
2414
2304 // Check if the extension is idle. 2415 // Check if the extension is idle.
2305 if (!IsExtensionIdle(extension_id)) 2416 if (reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE &&
2417 !IsExtensionIdle(extension_id))
2306 return; 2418 return;
2307 2419
2420 const Extension* extension = delayed_installs_.GetByID(extension_id);
2421 if (reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS &&
2422 !CheckImports(extension)) {
2423 return;
2424 }
2425
2308 FinishDelayedInstallation(extension_id); 2426 FinishDelayedInstallation(extension_id);
2309 } 2427 }
2310 2428
2311 void ExtensionService::FinishDelayedInstallation( 2429 void ExtensionService::FinishDelayedInstallation(
2312 const std::string& extension_id) { 2430 const std::string& extension_id) {
2313 scoped_refptr<const Extension> extension( 2431 scoped_refptr<const Extension> extension(
2314 GetPendingExtensionUpdate(extension_id)); 2432 GetPendingExtensionUpdate(extension_id));
2315 CHECK(extension.get()); 2433 CHECK(extension.get());
2316 delayed_updates_for_idle_.Remove(extension_id); 2434 delayed_installs_.Remove(extension_id);
2317 2435
2318 if (!extension_prefs_->FinishDelayedInstallInfo(extension_id)) 2436 if (!extension_prefs_->FinishDelayedInstallInfo(extension_id))
2319 NOTREACHED(); 2437 NOTREACHED();
2320 2438
2321 FinishInstallation(extension.get()); 2439 FinishInstallation(extension.get());
2322 } 2440 }
2323 2441
2324 void ExtensionService::FinishInstallation(const Extension* extension) { 2442 void ExtensionService::FinishInstallation(const Extension* extension) {
2325 const extensions::Extension* existing_extension = 2443 const extensions::Extension* existing_extension =
2326 GetInstalledExtension(extension->id()); 2444 GetInstalledExtension(extension->id());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2363 2481
2364 // If this is a new external extension that was disabled, alert the user 2482 // 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 2483 // so he can reenable it. We do this last so that it has already been
2366 // added to our list of extensions. 2484 // added to our list of extensions.
2367 if (unacknowledged_external) { 2485 if (unacknowledged_external) {
2368 UpdateExternalExtensionAlert(); 2486 UpdateExternalExtensionAlert();
2369 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", 2487 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
2370 EXTERNAL_EXTENSION_INSTALLED, 2488 EXTERNAL_EXTENSION_INSTALLED,
2371 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); 2489 EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
2372 } 2490 }
2491
2492 // Check extensions that may have been delayed only because this shared module
2493 // was not available.
2494 if (SharedModuleInfo::IsSharedModule(extension)) {
2495 MaybeFinishDelayedInstallations();
2496 }
2373 } 2497 }
2374 2498
2375 const Extension* ExtensionService::GetPendingExtensionUpdate( 2499 const Extension* ExtensionService::GetPendingExtensionUpdate(
2376 const std::string& id) const { 2500 const std::string& id) const {
2377 return delayed_updates_for_idle_.GetByID(id); 2501 return delayed_installs_.GetByID(id);
2378 } 2502 }
2379 2503
2380 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { 2504 void ExtensionService::TrackTerminatedExtension(const Extension* extension) {
2381 if (!terminated_extensions_.Contains(extension->id())) 2505 if (!terminated_extensions_.Contains(extension->id()))
2382 terminated_extensions_.Insert(make_scoped_refptr(extension)); 2506 terminated_extensions_.Insert(make_scoped_refptr(extension));
2383 2507
2384 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); 2508 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE);
2385 } 2509 }
2386 2510
2387 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { 2511 void ExtensionService::UntrackTerminatedExtension(const std::string& id) {
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 break; 2729 break;
2606 } 2730 }
2607 case chrome::NOTIFICATION_IMPORT_FINISHED: { 2731 case chrome::NOTIFICATION_IMPORT_FINISHED: {
2608 InitAfterImport(); 2732 InitAfterImport();
2609 break; 2733 break;
2610 } 2734 }
2611 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: { 2735 case chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED: {
2612 extensions::ExtensionHost* host = 2736 extensions::ExtensionHost* host =
2613 content::Details<extensions::ExtensionHost>(details).ptr(); 2737 content::Details<extensions::ExtensionHost>(details).ptr();
2614 std::string extension_id = host->extension_id(); 2738 std::string extension_id = host->extension_id();
2615 if (delayed_updates_for_idle_.Contains(extension_id)) { 2739 if (delayed_installs_.Contains(extension_id)) {
2616 // We were waiting for this extension to become idle, it now might have, 2740 // We were waiting for this extension to become idle, it now might have,
2617 // so maybe finish installation. 2741 // so maybe finish installation.
2618 base::MessageLoop::current()->PostDelayedTask( 2742 base::MessageLoop::current()->PostDelayedTask(
2619 FROM_HERE, 2743 FROM_HERE,
2620 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation, 2744 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation,
2621 AsWeakPtr(), extension_id), 2745 AsWeakPtr(), extension_id),
2622 base::TimeDelta::FromSeconds(kUpdateIdleDelay)); 2746 base::TimeDelta::FromSeconds(kUpdateIdleDelay));
2623 } 2747 }
2624 break; 2748 break;
2625 } 2749 }
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2801 DCHECK(!installs_delayed()); 2925 DCHECK(!installs_delayed());
2802 set_installs_delayed(true); 2926 set_installs_delayed(true);
2803 BrowserContext::GarbageCollectStoragePartitions( 2927 BrowserContext::GarbageCollectStoragePartitions(
2804 profile_, active_paths.Pass(), 2928 profile_, active_paths.Pass(),
2805 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished, 2929 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished,
2806 AsWeakPtr())); 2930 AsWeakPtr()));
2807 } 2931 }
2808 2932
2809 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { 2933 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() {
2810 set_installs_delayed(false); 2934 set_installs_delayed(false);
2935 MaybeFinishDelayedInstallations();
2936 }
2937
2938 void ExtensionService::MaybeFinishDelayedInstallations() {
2939 std::vector<std::string> to_be_installed;
2811 for (ExtensionSet::const_iterator it = delayed_installs_.begin(); 2940 for (ExtensionSet::const_iterator it = delayed_installs_.begin();
2812 it != delayed_installs_.end(); 2941 it != delayed_installs_.end();
2813 ++it) { 2942 ++it) {
2814 FinishDelayedInstallation((*it)->id()); 2943 to_be_installed.push_back((*it)->id());
2815 } 2944 }
2816 for (ExtensionSet::const_iterator it = delayed_updates_for_idle_.begin(); 2945 for (std::vector<std::string>::const_iterator it = to_be_installed.begin();
2817 it != delayed_updates_for_idle_.end(); 2946 it != to_be_installed.end();
2818 ++it) { 2947 ++it) {
2819 MaybeFinishDelayedInstallation((*it)->id()); 2948 MaybeFinishDelayedInstallation(*it);
2820 } 2949 }
2821 delayed_installs_.Clear();
2822 } 2950 }
2823 2951
2824 void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() { 2952 void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() {
2825 extension_prefs_->SetNeedsStorageGarbageCollection(true); 2953 extension_prefs_->SetNeedsStorageGarbageCollection(true);
2826 } 2954 }
2827 2955
2828 void ExtensionService::OnBlacklistUpdated() { 2956 void ExtensionService::OnBlacklistUpdated() {
2829 blacklist_->GetBlacklistedIDs( 2957 blacklist_->GetBlacklistedIDs(
2830 GenerateInstalledExtensionsSet()->GetIDs(), 2958 GenerateInstalledExtensionsSet()->GetIDs(),
2831 base::Bind(&ExtensionService::ManageBlacklist, 2959 base::Bind(&ExtensionService::ManageBlacklist,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2879 } 3007 }
2880 3008
2881 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { 3009 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) {
2882 update_observers_.AddObserver(observer); 3010 update_observers_.AddObserver(observer);
2883 } 3011 }
2884 3012
2885 void ExtensionService::RemoveUpdateObserver( 3013 void ExtensionService::RemoveUpdateObserver(
2886 extensions::UpdateObserver* observer) { 3014 extensions::UpdateObserver* observer) {
2887 update_observers_.RemoveObserver(observer); 3015 update_observers_.RemoveObserver(observer);
2888 } 3016 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698