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

Unified 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: done 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_service.cc
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 8d4f40eab60c862d49b9e8404d3c389aa47ba313..abc616b804d9093d40c3ad86deddb24574210061 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -105,6 +105,8 @@
#include "content/public/browser/notification_types.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/site_instance.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/common/pepper_plugin_info.h"
#include "extensions/common/error_utils.h"
#include "googleurl/src/gurl.h"
@@ -374,6 +376,7 @@ ExtensionService::ExtensionService(Profile* profile,
event_routers_initialized_(false),
update_once_all_providers_are_ready_(false),
browser_terminating_(false),
+ installs_delayed_(false),
wipeout_is_active_(false),
app_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
extension_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
@@ -589,6 +592,12 @@ const Extension* ExtensionService::GetExtensionById(
return GetExtensionById(id, include_mask);
}
+GURL ExtensionService::GetSiteForExtensionId(const std::string& extension_id) {
+ return content::SiteInstance::GetSiteForURL(
+ profile_,
+ Extension::GetBaseURLFromExtensionId(extension_id));
+}
+
const Extension* ExtensionService::GetExtensionById(
const std::string& id, int include_mask) const {
std::string lowercase_id = StringToLowerASCII(id);
@@ -621,8 +630,8 @@ void ExtensionService::Init() {
DCHECK(!ready_); // Can't redo init.
DCHECK_EQ(extensions_.size(), 0u);
- // TODO(mek): It might be cleaner to do the FinishIdleInstallInfo stuff here
- // instead of in installedloader
+ // TODO(mek): It might be cleaner to do the FinishDelayedInstallInfo stuff
+ // here instead of in installedloader.
component_loader_->LoadAll();
extensions::InstalledLoader(this).LoadAllExtensions();
@@ -652,6 +661,11 @@ void ExtensionService::Init() {
GarbageCollectExtensions();
}
}
+
+ if (extension_prefs_->NeedsStorageGarbageCollection()) {
+ GarbageCollectIsolatedStorage();
+ extension_prefs_->SetNeedsStorageGarbageCollection(false);
+ }
}
bool ExtensionService::UpdateExtension(const std::string& id,
@@ -783,7 +797,7 @@ void ExtensionService::ReloadExtensionWithEvents(
path = unloaded_extension_paths_[extension_id];
}
- if (pending_extension_updates_.Contains(extension_id)) {
+ if (delayed_updates_for_idle_.Contains(extension_id)) {
FinishDelayedInstallation(extension_id);
return;
}
@@ -881,14 +895,22 @@ bool ExtensionService::UninstallExtension(
launch_web_url_origin = launch_web_url_origin.GetOrigin();
bool is_storage_isolated = extension->is_storage_isolated();
- if (extension->is_hosted_app() &&
- !profile_->GetExtensionSpecialStoragePolicy()->
- IsStorageProtected(launch_web_url_origin)) {
- extensions::DataDeleter::StartDeleting(
- profile_, extension_id, launch_web_url_origin, is_storage_isolated);
+ if (is_storage_isolated) {
+ BrowserContext::AsyncObliterateStoragePartition(
+ profile_,
+ GetSiteForExtensionId(extension_id),
+ base::Bind(&ExtensionService::OnNeedsToGarbageCollectIsolatedStorage,
+ AsWeakPtr()));
+ } else {
+ if (extension->is_hosted_app() &&
+ !profile_->GetExtensionSpecialStoragePolicy()->
+ IsStorageProtected(launch_web_url_origin)) {
+ extensions::DataDeleter::StartDeleting(
+ profile_, extension_id, launch_web_url_origin);
+ }
+ extensions::DataDeleter::StartDeleting(profile_, extension_id,
+ extension->url());
}
- extensions::DataDeleter::StartDeleting(
- profile_, extension_id, extension->url(), is_storage_isolated);
UntrackTerminatedExtension(extension_id);
@@ -906,7 +928,8 @@ bool ExtensionService::UninstallExtension(
extension_sync_bundle_.ProcessDeletion(extension_id, sync_change);
}
- pending_extension_updates_.Remove(extension_id);
+ delayed_updates_for_idle_.Remove(extension_id);
+ delayed_installs_.Remove(extension_id);
// Track the uninstallation.
UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2);
@@ -2071,7 +2094,7 @@ void ExtensionService::GarbageCollectExtensions() {
extension_paths.insert(std::make_pair(info->at(i)->extension_id,
info->at(i)->extension_path));
- info = extension_prefs_->GetAllIdleInstallInfo();
+ info = extension_prefs_->GetAllDelayedInstallInfo();
for (size_t i = 0; i < info->size(); ++i)
extension_paths.insert(std::make_pair(info->at(i)->extension_id,
info->at(i)->extension_path));
@@ -2203,8 +2226,8 @@ void ExtensionService::AddComponentExtension(const Extension* extension) {
<< old_version_string << "' to " << extension->version()->GetString();
AddNewOrUpdatedExtension(extension,
- syncer::StringOrdinal(),
- Extension::ENABLED_COMPONENT);
+ Extension::ENABLED_COMPONENT,
+ syncer::StringOrdinal());
return;
}
@@ -2463,15 +2486,14 @@ void ExtensionService::OnExtensionInstalled(
// auto-acknowledge any extension that came from one of them.
if (extension->location() == Extension::EXTERNAL_POLICY_DOWNLOAD)
AcknowledgeExternalExtension(extension->id());
-
+ const Extension::State initial_state =
+ initial_enable ? Extension::ENABLED : Extension::DISABLED;
if (ShouldDelayExtensionUpdate(id, wait_for_idle)) {
- extension_prefs_->SetIdleInstallInfo(
- extension,
- initial_enable ? Extension::ENABLED : Extension::DISABLED,
- page_ordinal);
+ extension_prefs_->SetDelayedInstallInfo(extension, initial_state,
+ page_ordinal);
// Transfer ownership of |extension|.
- pending_extension_updates_.Insert(extension);
+ delayed_updates_for_idle_.Insert(extension);
// Notify extension of available update.
extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent(
@@ -2479,17 +2501,19 @@ void ExtensionService::OnExtensionInstalled(
return;
}
- // Transfer ownership of |extension|.
- AddNewOrUpdatedExtension(
- extension,
- page_ordinal,
- initial_enable ? Extension::ENABLED : Extension::DISABLED);
+ if (installs_delayed()) {
+ extension_prefs_->SetDelayedInstallInfo(extension, initial_state,
+ page_ordinal);
+ delayed_installs_.Insert(extension);
+ } else {
+ AddNewOrUpdatedExtension(extension, initial_state, page_ordinal);
+ }
}
void ExtensionService::AddNewOrUpdatedExtension(
const Extension* extension,
- const syncer::StringOrdinal& page_ordinal,
- Extension::State initial_state) {
+ Extension::State initial_state,
+ const syncer::StringOrdinal& page_ordinal) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
extension_prefs_->OnExtensionInstalled(
@@ -2497,20 +2521,13 @@ void ExtensionService::AddNewOrUpdatedExtension(
initial_state,
page_ordinal);
- // Unpacked extensions default to allowing file access, but if that has been
- // overridden, don't reset the value.
- if (Extension::ShouldAlwaysAllowFileAccess(extension->location()) &&
- !extension_prefs_->HasAllowFileAccessSetting(extension->id())) {
- extension_prefs_->SetAllowFileAccess(extension->id(), true);
- }
-
FinishInstallation(extension);
}
void ExtensionService::MaybeFinishDelayedInstallation(
const std::string& extension_id) {
// Check if the extension already got updated.
- if (!pending_extension_updates_.Contains(extension_id))
+ if (!delayed_updates_for_idle_.Contains(extension_id))
return;
// Check if the extension is idle.
if (!IsExtensionIdle(extension_id))
@@ -2524,9 +2541,9 @@ void ExtensionService::FinishDelayedInstallation(
scoped_refptr<const Extension> extension(
GetPendingExtensionUpdate(extension_id));
CHECK(extension);
- pending_extension_updates_.Remove(extension_id);
+ delayed_updates_for_idle_.Remove(extension_id);
- if (!extension_prefs_->FinishIdleInstallInfo(extension_id))
+ if (!extension_prefs_->FinishDelayedInstallInfo(extension_id))
NOTREACHED();
FinishInstallation(extension);
@@ -2540,6 +2557,13 @@ void ExtensionService::FinishInstallation(const Extension* extension) {
bool unacknowledged_external = IsUnacknowledgedExternalExtension(extension);
+ // Unpacked extensions default to allowing file access, but if that has been
+ // overridden, don't reset the value.
+ if (Extension::ShouldAlwaysAllowFileAccess(extension->location()) &&
+ !extension_prefs_->HasAllowFileAccessSetting(extension->id())) {
+ extension_prefs_->SetAllowFileAccess(extension->id(), true);
+ }
+
AddExtension(extension);
#if defined(ENABLE_THEMES)
@@ -2569,7 +2593,7 @@ void ExtensionService::FinishInstallation(const Extension* extension) {
const Extension* ExtensionService::GetPendingExtensionUpdate(
const std::string& id) const {
- return pending_extension_updates_.GetByID(id);
+ return delayed_updates_for_idle_.GetByID(id);
}
void ExtensionService::TrackTerminatedExtension(const Extension* extension) {
@@ -2815,7 +2839,7 @@ void ExtensionService::Observe(int type,
extensions::ExtensionHost* host =
content::Details<extensions::ExtensionHost>(details).ptr();
std::string extension_id = host->extension_id();
- if (pending_extension_updates_.Contains(extension_id)) {
+ if (delayed_updates_for_idle_.Contains(extension_id)) {
// We were waiting for this extension to become idle, it now might have,
// so maybe finish installation.
MessageLoop::current()->PostDelayedTask(
@@ -3103,6 +3127,46 @@ bool ExtensionService::ShouldDelayExtensionUpdate(
}
}
+void ExtensionService::GarbageCollectIsolatedStorage() {
+ scoped_ptr<base::hash_set<FilePath> > active_paths(
+ new base::hash_set<FilePath>());
+ for (ExtensionSet::const_iterator it = extensions_.begin();
+ it != extensions_.end(); ++it) {
+ if ((*it)->is_storage_isolated()) {
+ active_paths->insert(
+ BrowserContext::GetStoragePartitionForSite(
+ profile_,
+ GetSiteForExtensionId((*it)->id()))->GetPath());
+ }
+ }
+
+ DCHECK(!installs_delayed());
+ set_installs_delayed(true);
+ BrowserContext::GarbageCollectStoragePartitions(
+ profile_, active_paths.Pass(),
+ base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished,
+ AsWeakPtr()));
+}
+
+void ExtensionService::OnGarbageCollectIsolatedStorageFinished() {
+ set_installs_delayed(false);
+ for (ExtensionSet::const_iterator it = delayed_installs_.begin();
+ it != delayed_installs_.end();
+ ++it) {
+ FinishDelayedInstallation((*it)->id());
+ }
+ for (ExtensionSet::const_iterator it = delayed_updates_for_idle_.begin();
+ it != delayed_updates_for_idle_.end();
+ ++it) {
+ MaybeFinishDelayedInstallation((*it)->id());
+ }
+ delayed_installs_.Clear();
+}
+
+void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() {
+ extension_prefs_->SetNeedsStorageGarbageCollection(true);
+}
+
void ExtensionService::OnBlacklistUpdated() {
blacklist_->GetBlacklistedIDs(
GenerateInstalledExtensionsSet()->GetIDs(),
« no previous file with comments | « chrome/browser/extensions/extension_service.h ('k') | chrome/browser/extensions/extension_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698