| Index: chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc
|
| diff --git a/chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc b/chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc
|
| deleted file mode 100644
|
| index 30e976a259159b9dc0d56772648cdf8d0d5f8ec8..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.cc
|
| +++ /dev/null
|
| @@ -1,273 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/extensions/api/storage/settings_storage_quota_enforcer.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/json/json_writer.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "extensions/browser/value_store/value_store_util.h"
|
| -#include "extensions/common/extension_api.h"
|
| -
|
| -namespace util = value_store_util;
|
| -
|
| -namespace extensions {
|
| -
|
| -namespace {
|
| -
|
| -// Resources there are a quota for.
|
| -enum Resource {
|
| - QUOTA_BYTES,
|
| - QUOTA_BYTES_PER_ITEM,
|
| - MAX_ITEMS
|
| -};
|
| -
|
| -// Allocates a setting in a record of total and per-setting usage.
|
| -void Allocate(
|
| - const std::string& key,
|
| - const base::Value& value,
|
| - size_t* used_total,
|
| - std::map<std::string, size_t>* used_per_setting) {
|
| - // Calculate the setting size based on its JSON serialization size.
|
| - // TODO(kalman): Does this work with different encodings?
|
| - // TODO(kalman): This is duplicating work that the leveldb delegate
|
| - // implementation is about to do, and it would be nice to avoid this.
|
| - std::string value_as_json;
|
| - base::JSONWriter::Write(&value, &value_as_json);
|
| - size_t new_size = key.size() + value_as_json.size();
|
| - size_t existing_size = (*used_per_setting)[key];
|
| -
|
| - *used_total += (new_size - existing_size);
|
| - (*used_per_setting)[key] = new_size;
|
| -}
|
| -
|
| -// Frees the allocation of a setting in a record of total and per-setting usage.
|
| -void Free(
|
| - size_t* used_total,
|
| - std::map<std::string, size_t>* used_per_setting,
|
| - const std::string& key) {
|
| - *used_total -= (*used_per_setting)[key];
|
| - used_per_setting->erase(key);
|
| -}
|
| -
|
| -scoped_ptr<ValueStore::Error> QuotaExceededError(Resource resource,
|
| - scoped_ptr<std::string> key) {
|
| - const char* name = NULL;
|
| - // TODO(kalman): These hisograms are both silly and untracked. Fix.
|
| - switch (resource) {
|
| - case QUOTA_BYTES:
|
| - name = "QUOTA_BYTES";
|
| - UMA_HISTOGRAM_COUNTS_100(
|
| - "Extensions.SettingsQuotaExceeded.TotalBytes", 1);
|
| - break;
|
| - case QUOTA_BYTES_PER_ITEM:
|
| - name = "QUOTA_BYTES_PER_ITEM";
|
| - UMA_HISTOGRAM_COUNTS_100(
|
| - "Extensions.SettingsQuotaExceeded.BytesPerSetting", 1);
|
| - break;
|
| - case MAX_ITEMS:
|
| - name = "MAX_ITEMS";
|
| - UMA_HISTOGRAM_COUNTS_100(
|
| - "Extensions.SettingsQuotaExceeded.KeyCount", 1);
|
| - break;
|
| - }
|
| - CHECK(name);
|
| - return make_scoped_ptr(new ValueStore::Error(
|
| - ValueStore::QUOTA_EXCEEDED,
|
| - base::StringPrintf("%s quota exceeded", name),
|
| - key.Pass()));
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -SettingsStorageQuotaEnforcer::SettingsStorageQuotaEnforcer(
|
| - const Limits& limits, ValueStore* delegate)
|
| - : limits_(limits), delegate_(delegate), used_total_(0) {
|
| - CalculateUsage();
|
| -}
|
| -
|
| -SettingsStorageQuotaEnforcer::~SettingsStorageQuotaEnforcer() {}
|
| -
|
| -size_t SettingsStorageQuotaEnforcer::GetBytesInUse(const std::string& key) {
|
| - std::map<std::string, size_t>::iterator maybe_used =
|
| - used_per_setting_.find(key);
|
| - return maybe_used == used_per_setting_.end() ? 0u : maybe_used->second;
|
| -}
|
| -
|
| -size_t SettingsStorageQuotaEnforcer::GetBytesInUse(
|
| - const std::vector<std::string>& keys) {
|
| - size_t used = 0;
|
| - for (std::vector<std::string>::const_iterator it = keys.begin();
|
| - it != keys.end(); ++it) {
|
| - used += GetBytesInUse(*it);
|
| - }
|
| - return used;
|
| -}
|
| -
|
| -size_t SettingsStorageQuotaEnforcer::GetBytesInUse() {
|
| - // All ValueStore implementations rely on GetBytesInUse being
|
| - // implemented here.
|
| - return used_total_;
|
| -}
|
| -
|
| -ValueStore::ReadResult SettingsStorageQuotaEnforcer::Get(
|
| - const std::string& key) {
|
| - return delegate_->Get(key);
|
| -}
|
| -
|
| -ValueStore::ReadResult SettingsStorageQuotaEnforcer::Get(
|
| - const std::vector<std::string>& keys) {
|
| - return delegate_->Get(keys);
|
| -}
|
| -
|
| -ValueStore::ReadResult SettingsStorageQuotaEnforcer::Get() {
|
| - return delegate_->Get();
|
| -}
|
| -
|
| -ValueStore::WriteResult SettingsStorageQuotaEnforcer::Set(
|
| - WriteOptions options, const std::string& key, const base::Value& value) {
|
| - size_t new_used_total = used_total_;
|
| - std::map<std::string, size_t> new_used_per_setting = used_per_setting_;
|
| - Allocate(key, value, &new_used_total, &new_used_per_setting);
|
| -
|
| - if (!(options & IGNORE_QUOTA)) {
|
| - if (new_used_total > limits_.quota_bytes) {
|
| - return MakeWriteResult(
|
| - QuotaExceededError(QUOTA_BYTES, util::NewKey(key)));
|
| - }
|
| - if (new_used_per_setting[key] > limits_.quota_bytes_per_item) {
|
| - return MakeWriteResult(
|
| - QuotaExceededError(QUOTA_BYTES_PER_ITEM, util::NewKey(key)));
|
| - }
|
| - if (new_used_per_setting.size() > limits_.max_items)
|
| - return MakeWriteResult(QuotaExceededError(MAX_ITEMS, util::NewKey(key)));
|
| - }
|
| -
|
| - WriteResult result = delegate_->Set(options, key, value);
|
| - if (result->HasError()) {
|
| - return result.Pass();
|
| - }
|
| -
|
| - used_total_ = new_used_total;
|
| - used_per_setting_.swap(new_used_per_setting);
|
| - return result.Pass();
|
| -}
|
| -
|
| -ValueStore::WriteResult SettingsStorageQuotaEnforcer::Set(
|
| - WriteOptions options, const base::DictionaryValue& values) {
|
| - size_t new_used_total = used_total_;
|
| - std::map<std::string, size_t> new_used_per_setting = used_per_setting_;
|
| - for (base::DictionaryValue::Iterator it(values); !it.IsAtEnd();
|
| - it.Advance()) {
|
| - Allocate(it.key(), it.value(), &new_used_total, &new_used_per_setting);
|
| -
|
| - if (!(options & IGNORE_QUOTA) &&
|
| - new_used_per_setting[it.key()] > limits_.quota_bytes_per_item) {
|
| - return MakeWriteResult(
|
| - QuotaExceededError(QUOTA_BYTES_PER_ITEM, util::NewKey(it.key())));
|
| - }
|
| - }
|
| -
|
| - if (!(options & IGNORE_QUOTA)) {
|
| - if (new_used_total > limits_.quota_bytes)
|
| - return MakeWriteResult(QuotaExceededError(QUOTA_BYTES, util::NoKey()));
|
| - if (new_used_per_setting.size() > limits_.max_items)
|
| - return MakeWriteResult(QuotaExceededError(MAX_ITEMS, util::NoKey()));
|
| - }
|
| -
|
| - WriteResult result = delegate_->Set(options, values);
|
| - if (result->HasError()) {
|
| - return result.Pass();
|
| - }
|
| -
|
| - used_total_ = new_used_total;
|
| - used_per_setting_ = new_used_per_setting;
|
| - return result.Pass();
|
| -}
|
| -
|
| -ValueStore::WriteResult SettingsStorageQuotaEnforcer::Remove(
|
| - const std::string& key) {
|
| - WriteResult result = delegate_->Remove(key);
|
| - if (result->HasError()) {
|
| - return result.Pass();
|
| - }
|
| - Free(&used_total_, &used_per_setting_, key);
|
| - return result.Pass();
|
| -}
|
| -
|
| -ValueStore::WriteResult SettingsStorageQuotaEnforcer::Remove(
|
| - const std::vector<std::string>& keys) {
|
| - WriteResult result = delegate_->Remove(keys);
|
| - if (result->HasError()) {
|
| - return result.Pass();
|
| - }
|
| -
|
| - for (std::vector<std::string>::const_iterator it = keys.begin();
|
| - it != keys.end(); ++it) {
|
| - Free(&used_total_, &used_per_setting_, *it);
|
| - }
|
| - return result.Pass();
|
| -}
|
| -
|
| -ValueStore::WriteResult SettingsStorageQuotaEnforcer::Clear() {
|
| - WriteResult result = delegate_->Clear();
|
| - if (result->HasError()) {
|
| - return result.Pass();
|
| - }
|
| -
|
| - used_per_setting_.clear();
|
| - used_total_ = 0;
|
| - return result.Pass();
|
| -}
|
| -
|
| -bool SettingsStorageQuotaEnforcer::Restore() {
|
| - if (!delegate_->Restore()) {
|
| - // If we failed, we can't calculate the usage - that's okay, though, because
|
| - // next time we Restore() (if it succeeds) we will recalculate usage anyway.
|
| - // So reset storage counters now to free up resources.
|
| - used_per_setting_.clear();
|
| - used_total_ = 0u;
|
| - return false;
|
| - }
|
| - CalculateUsage();
|
| - return true;
|
| -}
|
| -
|
| -bool SettingsStorageQuotaEnforcer::RestoreKey(const std::string& key) {
|
| - if (!delegate_->RestoreKey(key))
|
| - return false;
|
| -
|
| - ReadResult result = Get(key);
|
| - // If the key was deleted as a result of the Restore() call, free it.
|
| - if (!result->settings().HasKey(key) && ContainsKey(used_per_setting_, key))
|
| - Free(&used_total_, &used_per_setting_, key);
|
| - return true;
|
| -}
|
| -
|
| -void SettingsStorageQuotaEnforcer::CalculateUsage() {
|
| - ReadResult maybe_settings = delegate_->Get();
|
| - if (maybe_settings->HasError()) {
|
| - // Try to restore the database if it's corrupt.
|
| - if (maybe_settings->error().code == ValueStore::CORRUPTION &&
|
| - delegate_->Restore()) {
|
| - maybe_settings = delegate_->Get();
|
| - } else {
|
| - LOG(WARNING) << "Failed to get settings for quota:"
|
| - << maybe_settings->error().message;
|
| - return;
|
| - }
|
| - }
|
| -
|
| - for (base::DictionaryValue::Iterator it(maybe_settings->settings());
|
| - !it.IsAtEnd();
|
| - it.Advance()) {
|
| - Allocate(it.key(), it.value(), &used_total_, &used_per_setting_);
|
| - }
|
| -}
|
| -
|
| -} // namespace extensions
|
|
|