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

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

Issue 11419307: Garbage Collect the Storage directory on next profile start after an extension uninstall. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Basic code done. Created 8 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_service.h" 5 #include "chrome/browser/extensions/extension_service.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 #include "chrome/common/extensions/manifest.h" 102 #include "chrome/common/extensions/manifest.h"
103 #include "chrome/common/pref_names.h" 103 #include "chrome/common/pref_names.h"
104 #include "chrome/common/url_constants.h" 104 #include "chrome/common/url_constants.h"
105 #include "content/public/browser/browser_thread.h" 105 #include "content/public/browser/browser_thread.h"
106 #include "content/public/browser/devtools_agent_host_registry.h" 106 #include "content/public/browser/devtools_agent_host_registry.h"
107 #include "content/public/browser/devtools_manager.h" 107 #include "content/public/browser/devtools_manager.h"
108 #include "content/public/browser/notification_service.h" 108 #include "content/public/browser/notification_service.h"
109 #include "content/public/browser/notification_types.h" 109 #include "content/public/browser/notification_types.h"
110 #include "content/public/browser/plugin_service.h" 110 #include "content/public/browser/plugin_service.h"
111 #include "content/public/browser/render_process_host.h" 111 #include "content/public/browser/render_process_host.h"
112 #include "content/public/browser/storage_partition.h"
112 #include "content/public/common/pepper_plugin_info.h" 113 #include "content/public/common/pepper_plugin_info.h"
113 #include "extensions/common/error_utils.h" 114 #include "extensions/common/error_utils.h"
114 #include "googleurl/src/gurl.h" 115 #include "googleurl/src/gurl.h"
115 #include "grit/generated_resources.h" 116 #include "grit/generated_resources.h"
116 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 117 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
117 #include "sync/api/sync_change.h" 118 #include "sync/api/sync_change.h"
118 #include "sync/api/sync_error_factory.h" 119 #include "sync/api/sync_error_factory.h"
119 #include "webkit/database/database_tracker.h" 120 #include "webkit/database/database_tracker.h"
120 #include "webkit/database/database_util.h" 121 #include "webkit/database/database_util.h"
121 122
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 198
198 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { 199 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() {
199 } 200 }
200 201
201 ExtensionService::NaClModuleInfo::NaClModuleInfo() { 202 ExtensionService::NaClModuleInfo::NaClModuleInfo() {
202 } 203 }
203 204
204 ExtensionService::NaClModuleInfo::~NaClModuleInfo() { 205 ExtensionService::NaClModuleInfo::~NaClModuleInfo() {
205 } 206 }
206 207
208 ExtensionService::PendingInstall::PendingInstall(
209 const extensions::Extension* extension,
210 const syncer::StringOrdinal& page_ordinal,
211 bool has_requirement_errors,
212 bool wait_for_idle)
213 : extension(extension),
214 page_ordinal(page_ordinal),
215 has_requirement_errors(has_requirement_errors),
216 wait_for_idle(wait_for_idle) {
217 }
218
219 ExtensionService::PendingInstall::~PendingInstall() {
220 }
221
207 // ExtensionService. 222 // ExtensionService.
208 223
209 const char ExtensionService::kInstallDirectoryName[] = "Extensions"; 224 const char ExtensionService::kInstallDirectoryName[] = "Extensions";
210 225
211 const char ExtensionService::kLocalAppSettingsDirectoryName[] = 226 const char ExtensionService::kLocalAppSettingsDirectoryName[] =
212 "Local App Settings"; 227 "Local App Settings";
213 const char ExtensionService::kLocalExtensionSettingsDirectoryName[] = 228 const char ExtensionService::kLocalExtensionSettingsDirectoryName[] =
214 "Local Extension Settings"; 229 "Local Extension Settings";
215 const char ExtensionService::kSyncAppSettingsDirectoryName[] = 230 const char ExtensionService::kSyncAppSettingsDirectoryName[] =
216 "Sync App Settings"; 231 "Sync App Settings";
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 show_extensions_prompts_(true), 382 show_extensions_prompts_(true),
368 install_updates_when_idle_(true), 383 install_updates_when_idle_(true),
369 ready_(false), 384 ready_(false),
370 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 385 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
371 menu_manager_(profile), 386 menu_manager_(profile),
372 app_notification_manager_( 387 app_notification_manager_(
373 new extensions::AppNotificationManager(profile)), 388 new extensions::AppNotificationManager(profile)),
374 event_routers_initialized_(false), 389 event_routers_initialized_(false),
375 update_once_all_providers_are_ready_(false), 390 update_once_all_providers_are_ready_(false),
376 browser_terminating_(false), 391 browser_terminating_(false),
392 delay_all_installs_(false),
377 app_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 393 app_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
378 extension_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), 394 extension_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
379 app_shortcut_manager_(profile) { 395 app_shortcut_manager_(profile) {
380 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 396 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
381 397
382 // Figure out if extension installation should be enabled. 398 // Figure out if extension installation should be enabled.
383 if (command_line->HasSwitch(switches::kDisableExtensions) || 399 if (command_line->HasSwitch(switches::kDisableExtensions) ||
384 profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { 400 profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) {
385 extensions_enabled_ = false; 401 extensions_enabled_ = false;
386 } 402 }
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 RegisterForImportFinished(); 627 RegisterForImportFinished();
612 } else { 628 } else {
613 // TODO(erikkay) this should probably be deferred to a future point 629 // TODO(erikkay) this should probably be deferred to a future point
614 // rather than running immediately at startup. 630 // rather than running immediately at startup.
615 CheckForExternalUpdates(); 631 CheckForExternalUpdates();
616 632
617 // TODO(erikkay) this should probably be deferred as well. 633 // TODO(erikkay) this should probably be deferred as well.
618 GarbageCollectExtensions(); 634 GarbageCollectExtensions();
619 } 635 }
620 } 636 }
637
638 if (extension_prefs_->NeedsStorageGarbageCollection()) {
639 GarbageCollectIsolatedStorage();
640 extension_prefs_->SetNeedsStorageGarbageCollection(false);
641 }
621 } 642 }
622 643
623 bool ExtensionService::UpdateExtension(const std::string& id, 644 bool ExtensionService::UpdateExtension(const std::string& id,
624 const FilePath& extension_path, 645 const FilePath& extension_path,
625 const GURL& download_url, 646 const GURL& download_url,
626 CrxInstaller** out_crx_installer) { 647 CrxInstaller** out_crx_installer) {
627 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 648 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
628 if (browser_terminating_) { 649 if (browser_terminating_) {
629 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; 650 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown";
630 // Leak the temp file at extension_path. We don't want to add to the disk 651 // Leak the temp file at extension_path. We don't want to add to the disk
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 &extension_file_util::UninstallExtension, 863 &extension_file_util::UninstallExtension,
843 install_directory_, 864 install_directory_,
844 extension_id))) 865 extension_id)))
845 NOTREACHED(); 866 NOTREACHED();
846 } 867 }
847 868
848 GURL launch_web_url_origin(extension->launch_web_url()); 869 GURL launch_web_url_origin(extension->launch_web_url());
849 launch_web_url_origin = launch_web_url_origin.GetOrigin(); 870 launch_web_url_origin = launch_web_url_origin.GetOrigin();
850 bool is_storage_isolated = extension->is_storage_isolated(); 871 bool is_storage_isolated = extension->is_storage_isolated();
851 872
852 if (extension->is_hosted_app() && 873 if (is_storage_isolated) {
853 !profile_->GetExtensionSpecialStoragePolicy()-> 874 // TODO(ajwong): At teast abstract this into function.
854 IsStorageProtected(launch_web_url_origin)) { 875 const GURL& site = Extension::GetBaseURLFromExtensionId(extension_id);
855 extensions::DataDeleter::StartDeleting( 876 BrowserContext::AsyncObliterateStoragePartition(
856 profile_, extension_id, launch_web_url_origin, is_storage_isolated); 877 profile_, site,
878 // TODO(ajwong): We must bounce to UI thread and do correct cancelation.
Charlie Reis 2012/12/05 02:25:40 Not quite sure what this means. Also, long line b
awong 2012/12/08 01:45:23 Resolved it. I hadn't fixed the API to make sure t
879 base::Bind(&extensions::ExtensionPrefs::SetNeedsStorageGarbageCollection ,
880 base::Unretained(extension_prefs_), true));
881 } else {
882 if (extension->is_hosted_app() &&
883 !profile_->GetExtensionSpecialStoragePolicy()->
884 IsStorageProtected(launch_web_url_origin)) {
885 extensions::DataDeleter::StartDeleting(
886 profile_, extension_id, launch_web_url_origin);
887 }
888 extensions::DataDeleter::StartDeleting(profile_, extension_id,
889 extension->url());
857 } 890 }
858 extensions::DataDeleter::StartDeleting(
859 profile_, extension_id, extension->url(), is_storage_isolated);
860 891
861 UntrackTerminatedExtension(extension_id); 892 UntrackTerminatedExtension(extension_id);
862 893
863 // Notify interested parties that we've uninstalled this extension. 894 // Notify interested parties that we've uninstalled this extension.
864 content::NotificationService::current()->Notify( 895 content::NotificationService::current()->Notify(
865 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 896 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
866 content::Source<Profile>(profile_), 897 content::Source<Profile>(profile_),
867 content::Details<const Extension>(extension)); 898 content::Details<const Extension>(extension));
868 899
869 if (app_sync_bundle_.HasExtensionId(extension_id) && 900 if (app_sync_bundle_.HasExtensionId(extension_id) &&
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 child_process_logging::SetActiveExtensions(extension_ids); 2303 child_process_logging::SetActiveExtensions(extension_ids);
2273 } 2304 }
2274 2305
2275 void ExtensionService::OnExtensionInstalled( 2306 void ExtensionService::OnExtensionInstalled(
2276 const Extension* extension, 2307 const Extension* extension,
2277 const syncer::StringOrdinal& page_ordinal, 2308 const syncer::StringOrdinal& page_ordinal,
2278 bool has_requirement_errors, 2309 bool has_requirement_errors,
2279 bool wait_for_idle) { 2310 bool wait_for_idle) {
2280 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2311 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2281 2312
2313 // If installs are delayed, then disable.
Charlie Reis 2012/12/05 02:25:40 I guess I'm a bit confused by the names here. "On
awong 2012/12/08 01:45:23 Yeah, it confused me too. OnExtensionInstalled()
2314 if (delay_all_installs()) {
2315 pending_extension_installs_.push_back(
Matt Perry 2012/12/05 19:55:33 Can you explain why reusing the FinishDelayedInsta
awong 2012/12/05 21:01:57 I probably misunderstood the code. What I saw was
Matt Perry 2012/12/05 21:22:08 I think the main question is, exactly what do you
awong 2012/12/08 01:45:23 I've redone this a bit. Let me know what you think
2316 PendingInstall(extension, page_ordinal, has_requirement_errors,
2317 wait_for_idle));
2318 return;
2319 }
2320
2282 const std::string& id = extension->id(); 2321 const std::string& id = extension->id();
2283 bool initial_enable = ShouldEnableOnInstall(extension); 2322 bool initial_enable = ShouldEnableOnInstall(extension);
2284 const extensions::PendingExtensionInfo* pending_extension_info = NULL; 2323 const extensions::PendingExtensionInfo* pending_extension_info = NULL;
2285 if ((pending_extension_info = pending_extension_manager()->GetById(id))) { 2324 if ((pending_extension_info = pending_extension_manager()->GetById(id))) {
2286 if (!pending_extension_info->ShouldAllowInstall(*extension)) { 2325 if (!pending_extension_info->ShouldAllowInstall(*extension)) {
2287 pending_extension_manager()->Remove(id); 2326 pending_extension_manager()->Remove(id);
2288 2327
2289 LOG(WARNING) << "ShouldAllowInstall() returned false for " 2328 LOG(WARNING) << "ShouldAllowInstall() returned false for "
2290 << id << " of type " << extension->GetType() 2329 << id << " of type " << extension->GetType()
2291 << " and update URL " << extension->update_url().spec() 2330 << " and update URL " << extension->update_url().spec()
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
2975 // Delay installation if the extension listens for the onUpdateAvailable 3014 // Delay installation if the extension listens for the onUpdateAvailable
2976 // event. 3015 // event.
2977 return system_->event_router()->ExtensionHasEventListener( 3016 return system_->event_router()->ExtensionHasEventListener(
2978 extension_id, kOnUpdateAvailableEvent); 3017 extension_id, kOnUpdateAvailableEvent);
2979 } else { 3018 } else {
2980 // Delay installation if the extension is not idle. 3019 // Delay installation if the extension is not idle.
2981 return !IsExtensionIdle(extension_id); 3020 return !IsExtensionIdle(extension_id);
2982 } 3021 }
2983 } 3022 }
2984 3023
3024 void ExtensionService::GarbageCollectIsolatedStorage() {
3025 base::hash_set<FilePath> active_paths;
3026 for (ExtensionSet::const_iterator it = extensions_.begin();
3027 it != extensions_.end(); ++it) {
3028 if ((*it)->is_storage_isolated()) {
3029 // TODO(ajwong): This should be passed through effective url or something.
3030 active_paths.insert(
3031 BrowserContext::GetStoragePartitionForSite(
3032 profile_,
3033 Extension::GetBaseURLFromExtensionId((*it)->id()))->GetPath());
3034 }
3035 }
3036
3037 DCHECK(!delay_all_installs());
3038 set_delay_all_installs(true);
3039 BrowserContext::GarbageCollectStoragePartitions(
3040 profile_, &active_paths,
3041 base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished,
3042 AsWeakPtr()));
3043 }
3044
3045 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() {
3046 set_delay_all_installs(false);
3047 for (std::vector<PendingInstall>::const_iterator it =
3048 pending_extension_installs_.begin();
3049 it != pending_extension_installs_.end();
3050 ++it) {
3051 OnExtensionInstalled(it->extension, it->page_ordinal,
3052 it->has_requirement_errors, it->wait_for_idle);
3053 }
3054 pending_extension_installs_.clear();
3055 }
3056
2985 void ExtensionService::OnBlacklistUpdated() { 3057 void ExtensionService::OnBlacklistUpdated() {
2986 CheckManagementPolicy(); 3058 CheckManagementPolicy();
2987 } 3059 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698