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

Unified Diff: chrome/browser/extensions/extension_storage_monitor.cc

Issue 314563003: Handle promotion of ephemeral apps in the ExtensionStorageMonitor (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nit in comment Created 6 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_storage_monitor.cc
diff --git a/chrome/browser/extensions/extension_storage_monitor.cc b/chrome/browser/extensions/extension_storage_monitor.cc
index 9fda00f552466d294f78fefdcfff462d41c41466..1ad2d4255c626ed0106033986d73ebb4189ebbe2 100644
--- a/chrome/browser/extensions/extension_storage_monitor.cc
+++ b/chrome/browser/extensions/extension_storage_monitor.cc
@@ -54,6 +54,22 @@ const int64 kExtensionInitialThreshold = 1000 * kMBytes;
const char kNotificationIdFormat[] = "ExtensionStorageMonitor-$1-$2";
const char kSystemNotifierId[] = "ExtensionStorageMonitor";
+// A preference that stores the next threshold for displaying a notification
+// when an extension or app consumes excessive disk space. This will not be
+// set until the extension/app reaches the initial threshold.
+const char kPrefNextStorageThreshold[] = "next_storage_threshold";
+
+// If this preference is set to true, notifications will be suppressed when an
+// extension or app consumes excessive disk space.
+const char kPrefDisableStorageNotifications[] = "disable_storage_notifications";
+
+bool ShouldMonitorStorageFor(const Extension* extension) {
+ // Only monitor storage for extensions that are granted unlimited storage.
+ // Do not monitor storage for component extensions.
+ return extension->HasAPIPermission(APIPermission::kUnlimitedStorage) &&
+ extension->location() != Manifest::COMPONENT;
+}
+
} // namespace
// StorageEventObserver monitors the storage usage of extensions and lives on
@@ -94,6 +110,21 @@ class StorageEventObserver
quota_manager->AddStorageObserver(this, params);
}
+ // Updates the threshold for an extension already being monitored.
+ void UpdateThresholdForExtension(const std::string& extension_id,
+ int64 next_threshold) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ for (OriginStorageStateMap::iterator it = origin_state_map_.begin();
+ it != origin_state_map_.end();
+ ++it) {
+ if (it->second.extension_id == extension_id) {
+ it->second.next_threshold = next_threshold;
+ break;
+ }
+ }
+ }
+
// Deregister as an observer for the extension's storage events.
void StopObservingForExtension(const std::string& extension_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -181,16 +212,15 @@ ExtensionStorageMonitor::ExtensionStorageMonitor(
initial_ephemeral_threshold_(kEphemeralAppInitialThreshold),
observer_rate_(kStorageEventRateSec),
context_(context),
+ extension_prefs_(ExtensionPrefs::Get(context)),
+ extension_registry_observer_(this),
weak_ptr_factory_(this) {
- registrar_.Add(this,
- chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED,
- content::Source<content::BrowserContext>(context_));
+ DCHECK(extension_prefs_);
+
registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
content::Source<content::BrowserContext>(context_));
- ExtensionRegistry* registry = ExtensionRegistry::Get(context_);
- DCHECK(registry);
- registry->AddObserver(this);
+ extension_registry_observer_.Add(ExtensionRegistry::Get(context_));
}
ExtensionStorageMonitor::~ExtensionStorageMonitor() {}
@@ -200,12 +230,6 @@ void ExtensionStorageMonitor::Observe(
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
- case chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED: {
- const Extension* extension =
- content::Details<const Extension>(details).ptr();
- RemoveNotificationForExtension(extension->id());
- break;
- }
case chrome::NOTIFICATION_PROFILE_DESTROYED: {
StopMonitoringAll();
break;
@@ -218,7 +242,6 @@ void ExtensionStorageMonitor::Observe(
void ExtensionStorageMonitor::OnExtensionLoaded(
content::BrowserContext* browser_context,
const Extension* extension) {
- DCHECK(extension);
StartMonitoringStorage(extension);
}
@@ -226,10 +249,53 @@ void ExtensionStorageMonitor::OnExtensionUnloaded(
content::BrowserContext* browser_context,
const Extension* extension,
UnloadedExtensionInfo::Reason reason) {
- DCHECK(extension);
StopMonitoringStorage(extension->id());
}
+void ExtensionStorageMonitor::OnExtensionWillBeInstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ bool is_update,
+ bool from_ephemeral,
+ const std::string& old_name) {
+ // If an ephemeral app was promoted to a regular installed app, we may need to
+ // increase its next threshold.
+ if (!from_ephemeral || !ShouldMonitorStorageFor(extension))
+ return;
+
+ if (!enable_for_all_extensions_) {
+ // If monitoring is not enabled for installed extensions, just stop
+ // monitoring.
+ SetNextStorageThreshold(extension->id(), 0);
+ StopMonitoringStorage(extension->id());
+ return;
+ }
+
+ int64 next_threshold = GetNextStorageThresholdFromPrefs(extension->id());
+ if (next_threshold <= initial_extension_threshold_) {
+ // Clear the next threshold in the prefs. This effectively raises it to
+ // |initial_extension_threshold_|. If the current threshold is already
+ // higher than this, leave it as is.
+ SetNextStorageThreshold(extension->id(), 0);
+
+ if (storage_observer_.get()) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&StorageEventObserver::UpdateThresholdForExtension,
+ storage_observer_,
+ extension->id(),
+ initial_extension_threshold_));
+ }
+ }
+}
+
+void ExtensionStorageMonitor::OnExtensionUninstalled(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ RemoveNotificationForExtension(extension->id());
+}
+
std::string ExtensionStorageMonitor::GetNotificationId(
const std::string& extension_id) {
std::vector<std::string> placeholders;
@@ -250,9 +316,8 @@ void ExtensionStorageMonitor::OnStorageThresholdExceeded(
if (!extension)
return;
- ExtensionPrefs* prefs = ExtensionPrefs::Get(context_);
- DCHECK(prefs);
- prefs->SetNextStorageThreshold(extension->id(), next_threshold);
+ if (GetNextStorageThreshold(extension->id()) < next_threshold)
+ SetNextStorageThreshold(extension->id(), next_threshold);
const int kIconSize = message_center::kNotificationIconSize;
ExtensionResource resource = IconsInfo::GetIconResource(
@@ -332,9 +397,7 @@ void ExtensionStorageMonitor::DisableStorageMonitoring(
const std::string& extension_id) {
StopMonitoringStorage(extension_id);
- ExtensionPrefs* prefs = ExtensionPrefs::Get(context_);
- DCHECK(prefs);
- prefs->SetStorageNotificationEnabled(extension_id, false);
+ SetStorageNotificationEnabled(extension_id, false);
message_center::MessageCenter::Get()->RemoveNotification(
GetNotificationId(extension_id), false);
@@ -342,23 +405,17 @@ void ExtensionStorageMonitor::DisableStorageMonitoring(
void ExtensionStorageMonitor::StartMonitoringStorage(
const Extension* extension) {
- if (!extension->HasAPIPermission(APIPermission::kUnlimitedStorage))
- return;
-
- // Do not monitor storage for component extensions.
- if (extension->location() == Manifest::COMPONENT)
+ if (!ShouldMonitorStorageFor(extension))
return;
- ExtensionPrefs* prefs = ExtensionPrefs::Get(context_);
- DCHECK(prefs);
-
// First apply this feature only to experimental ephemeral apps. If it works
// well, roll it out to all extensions and apps.
- bool is_ephemeral = prefs->IsEphemeralApp(extension->id());
- if (!is_ephemeral && !enable_for_all_extensions_)
+ if (!enable_for_all_extensions_ &&
+ !extension_prefs_->IsEphemeralApp(extension->id())) {
return;
+ }
- if (!prefs->IsStorageNotificationEnabled(extension->id()))
+ if (!IsStorageNotificationEnabled(extension->id()))
return;
// Lazily create the storage monitor proxy on the IO thread.
@@ -379,14 +436,6 @@ void ExtensionStorageMonitor::StartMonitoringStorage(
if (extension->is_hosted_app())
storage_origin = AppLaunchInfo::GetLaunchWebURL(extension).GetOrigin();
- int next_threshold = prefs->GetNextStorageThreshold(extension->id());
- if (next_threshold == 0) {
- // The next threshold is written to the prefs after the initial threshold is
- // exceeded.
- next_threshold = is_ephemeral ? initial_ephemeral_threshold_
- : initial_extension_threshold_;
- }
-
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
@@ -395,7 +444,7 @@ void ExtensionStorageMonitor::StartMonitoringStorage(
quota_manager,
extension->id(),
storage_origin,
- next_threshold,
+ GetNextStorageThreshold(extension->id()),
observer_rate_));
}
@@ -413,9 +462,7 @@ void ExtensionStorageMonitor::StopMonitoringStorage(
}
void ExtensionStorageMonitor::StopMonitoringAll() {
- ExtensionRegistry* registry = ExtensionRegistry::Get(context_);
- DCHECK(registry);
- registry->RemoveObserver(this);
+ extension_registry_observer_.RemoveAll();
RemoveAllNotifications();
@@ -454,4 +501,64 @@ void ExtensionStorageMonitor::RemoveAllNotifications() {
notified_extension_ids_.clear();
}
+int64 ExtensionStorageMonitor::GetNextStorageThreshold(
+ const std::string& extension_id) const {
+ int next_threshold = GetNextStorageThresholdFromPrefs(extension_id);
+ if (next_threshold == 0) {
+ // The next threshold is written to the prefs after the initial threshold is
+ // exceeded.
+ next_threshold = extension_prefs_->IsEphemeralApp(extension_id)
+ ? initial_ephemeral_threshold_
+ : initial_extension_threshold_;
+ }
+ return next_threshold;
+}
+
+void ExtensionStorageMonitor::SetNextStorageThreshold(
+ const std::string& extension_id,
+ int64 next_threshold) {
+ extension_prefs_->UpdateExtensionPref(
+ extension_id,
+ kPrefNextStorageThreshold,
+ next_threshold > 0
+ ? new base::StringValue(base::Int64ToString(next_threshold))
+ : NULL);
+}
+
+int64 ExtensionStorageMonitor::GetNextStorageThresholdFromPrefs(
+ const std::string& extension_id) const {
+ std::string next_threshold_str;
+ if (extension_prefs_->ReadPrefAsString(
+ extension_id, kPrefNextStorageThreshold, &next_threshold_str)) {
+ int64 next_threshold;
+ if (base::StringToInt64(next_threshold_str, &next_threshold))
+ return next_threshold;
+ }
+
+ // A return value of zero indicates that the initial threshold has not yet
+ // been reached.
+ return 0;
+}
+
+bool ExtensionStorageMonitor::IsStorageNotificationEnabled(
+ const std::string& extension_id) const {
+ bool disable_notifications;
+ if (extension_prefs_->ReadPrefAsBoolean(extension_id,
+ kPrefDisableStorageNotifications,
+ &disable_notifications)) {
+ return !disable_notifications;
+ }
+
+ return true;
+}
+
+void ExtensionStorageMonitor::SetStorageNotificationEnabled(
+ const std::string& extension_id,
+ bool enable_notifications) {
+ extension_prefs_->UpdateExtensionPref(
+ extension_id,
+ kPrefDisableStorageNotifications,
+ enable_notifications ? NULL : new base::FundamentalValue(true));
+}
+
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698