summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-28 08:46:35 +0000
committerkalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-28 08:46:35 +0000
commit6c1a852ad00df937a1c9ce8e15f9940e72d24386 (patch)
treea47a80b970c86fefa48b6809da26d9ad02509899 /chrome
parent7a338dcbd7a00980a53824b9901beb2344047a19 (diff)
downloadchromium_src-6c1a852ad00df937a1c9ce8e15f9940e72d24386.zip
chromium_src-6c1a852ad00df937a1c9ce8e15f9940e72d24386.tar.gz
chromium_src-6c1a852ad00df937a1c9ce8e15f9940e72d24386.tar.bz2
Extension Storage API: expose storage quota information to extensions, via:
- exposing the constants as properties on chrome.storage.{sync,local}, and - adding a new API call "getBytesInUse". BUG=110980, 110583, 110663 TEST=unit_tests --gtest_filter=ExtensionSettingsFrontendTest*, browser_tests --gtest_filter=ExtensionSetting* Review URL: http://codereview.chromium.org/9284013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119598 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc1
-rw-r--r--chrome/browser/extensions/settings/failing_settings_storage.cc23
-rw-r--r--chrome/browser/extensions/settings/failing_settings_storage.h5
-rw-r--r--chrome/browser/extensions/settings/settings_api.cc43
-rw-r--r--chrome/browser/extensions/settings/settings_api.h8
-rw-r--r--chrome/browser/extensions/settings/settings_frontend.cc71
-rw-r--r--chrome/browser/extensions/settings/settings_frontend.h10
-rw-r--r--chrome/browser/extensions/settings/settings_leveldb_storage.cc21
-rw-r--r--chrome/browser/extensions/settings/settings_leveldb_storage.h3
-rw-r--r--chrome/browser/extensions/settings/settings_quota_unittest.cc39
-rw-r--r--chrome/browser/extensions/settings/settings_storage.h9
-rw-r--r--chrome/browser/extensions/settings/settings_storage_quota_enforcer.cc55
-rw-r--r--chrome/browser/extensions/settings/settings_storage_quota_enforcer.h19
-rw-r--r--chrome/browser/extensions/settings/syncable_settings_storage.cc16
-rw-r--r--chrome/browser/extensions/settings/syncable_settings_storage.h5
-rw-r--r--chrome/browser/extensions/settings/testing_settings_storage.cc21
-rw-r--r--chrome/browser/extensions/settings/testing_settings_storage.h5
-rw-r--r--chrome/browser/extensions/settings/weak_unlimited_settings_storage.cc14
-rw-r--r--chrome/browser/extensions/settings/weak_unlimited_settings_storage.h3
-rw-r--r--chrome/common/extensions/api/storage.json69
-rw-r--r--chrome/common/extensions/docs/storage.html307
-rw-r--r--chrome/renderer/resources/extensions/schema_generated_bindings.js2
-rw-r--r--chrome/renderer/resources/extensions/storage_custom_bindings.js10
-rw-r--r--chrome/test/data/extensions/api_test/settings/simple_test/background.js46
24 files changed, 707 insertions, 98 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 30e3e3a..2a0d409 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -443,6 +443,7 @@ void FactoryRegistry::ResetFunctions() {
RegisterFunction<extensions::SetSettingsFunction>();
RegisterFunction<extensions::RemoveSettingsFunction>();
RegisterFunction<extensions::ClearSettingsFunction>();
+ RegisterFunction<extensions::GetBytesInUseSettingsFunction>();
// Content settings.
RegisterFunction<GetResourceIdentifiersFunction>();
diff --git a/chrome/browser/extensions/settings/failing_settings_storage.cc b/chrome/browser/extensions/settings/failing_settings_storage.cc
index 8e15ace..3083ddf 100644
--- a/chrome/browser/extensions/settings/failing_settings_storage.cc
+++ b/chrome/browser/extensions/settings/failing_settings_storage.cc
@@ -1,9 +1,11 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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/settings/failing_settings_storage.h"
+#include "base/logging.h"
+
namespace extensions {
namespace {
@@ -20,6 +22,25 @@ SettingsStorage::WriteResult WriteResultError() {
} // namespace
+size_t FailingSettingsStorage::GetBytesInUse(const std::string& key) {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
+size_t FailingSettingsStorage::GetBytesInUse(
+ const std::vector<std::string>& keys) {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
+size_t FailingSettingsStorage::GetBytesInUse() {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
SettingsStorage::ReadResult FailingSettingsStorage::Get(
const std::string& key) {
return ReadResultError();
diff --git a/chrome/browser/extensions/settings/failing_settings_storage.h b/chrome/browser/extensions/settings/failing_settings_storage.h
index ad97cfc..e99b7ea 100644
--- a/chrome/browser/extensions/settings/failing_settings_storage.h
+++ b/chrome/browser/extensions/settings/failing_settings_storage.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -17,6 +17,9 @@ class FailingSettingsStorage : public SettingsStorage {
FailingSettingsStorage() {}
// SettingsStorage implementation.
+ virtual size_t GetBytesInUse(const std::string& key) OVERRIDE;
+ virtual size_t GetBytesInUse(const std::vector<std::string>& keys) OVERRIDE;
+ virtual size_t GetBytesInUse() OVERRIDE;
virtual ReadResult Get(const std::string& key) OVERRIDE;
virtual ReadResult Get(const std::vector<std::string>& keys) OVERRIDE;
virtual ReadResult Get() OVERRIDE;
diff --git a/chrome/browser/extensions/settings/settings_api.cc b/chrome/browser/extensions/settings/settings_api.cc
index ba277ff..cfb749c 100644
--- a/chrome/browser/extensions/settings/settings_api.cc
+++ b/chrome/browser/extensions/settings/settings_api.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -143,7 +143,7 @@ static void GetModificationQuotaLimitHeuristics(
bool GetSettingsFunction::RunWithStorage(SettingsStorage* storage) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- Value *input;
+ Value* input = NULL;
EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));
switch (input->GetType()) {
@@ -182,9 +182,44 @@ bool GetSettingsFunction::RunWithStorage(SettingsStorage* storage) {
}
}
+bool GetBytesInUseSettingsFunction::RunWithStorage(SettingsStorage* storage) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ Value* input = NULL;
+ EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));
+
+ size_t bytes_in_use = 0;
+
+ switch (input->GetType()) {
+ case Value::TYPE_NULL:
+ bytes_in_use = storage->GetBytesInUse();
+ break;
+
+ case Value::TYPE_STRING: {
+ std::string as_string;
+ input->GetAsString(&as_string);
+ bytes_in_use = storage->GetBytesInUse(as_string);
+ break;
+ }
+
+ case Value::TYPE_LIST: {
+ std::vector<std::string> as_string_list;
+ AddAllStringValues(*static_cast<ListValue*>(input), &as_string_list);
+ bytes_in_use = storage->GetBytesInUse(as_string_list);
+ break;
+ }
+
+ default:
+ error_ = kUnsupportedArgumentType;
+ return false;
+ }
+
+ result_.reset(Value::CreateIntegerValue(bytes_in_use));
+ return true;
+}
+
bool SetSettingsFunction::RunWithStorage(SettingsStorage* storage) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DictionaryValue* input;
+ DictionaryValue* input = NULL;
EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input));
return UseWriteResult(storage->Set(SettingsStorage::DEFAULTS, *input));
}
@@ -196,7 +231,7 @@ void SetSettingsFunction::GetQuotaLimitHeuristics(
bool RemoveSettingsFunction::RunWithStorage(SettingsStorage* storage) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- Value *input;
+ Value* input = NULL;
EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));
switch (input->GetType()) {
diff --git a/chrome/browser/extensions/settings/settings_api.h b/chrome/browser/extensions/settings/settings_api.h
index d8d2d5e..1728e9f 100644
--- a/chrome/browser/extensions/settings/settings_api.h
+++ b/chrome/browser/extensions/settings/settings_api.h
@@ -99,6 +99,14 @@ class ClearSettingsFunction : public SettingsFunction {
QuotaLimitHeuristics* heuristics) const OVERRIDE;
};
+class GetBytesInUseSettingsFunction : public SettingsFunction {
+ public:
+ DECLARE_EXTENSION_FUNCTION_NAME("storage.getBytesInUse");
+
+ protected:
+ virtual bool RunWithStorage(SettingsStorage* storage) OVERRIDE;
+};
+
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_SETTINGS_SETTINGS_API_H_
diff --git a/chrome/browser/extensions/settings/settings_frontend.cc b/chrome/browser/extensions/settings/settings_frontend.cc
index 8d7d914..1c2d92c 100644
--- a/chrome/browser/extensions/settings/settings_frontend.cc
+++ b/chrome/browser/extensions/settings/settings_frontend.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/file_path.h"
+#include "base/string_number_conversions.h"
#include "chrome/browser/extensions/extension_event_names.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_service.h"
@@ -14,6 +15,7 @@
#include "chrome/browser/extensions/settings/settings_leveldb_storage.h"
#include "chrome/browser/extensions/settings/weak_unlimited_settings_storage.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/api/extension_api.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
@@ -23,29 +25,6 @@ namespace extensions {
namespace {
-const SettingsStorageQuotaEnforcer::Limits kSyncQuota = {
- // 100K should be enough for simple use, but this can be increased as demand
- // increases.
- 100 * 1024,
-
- // Sync supports 5k per settings, so be a bit more restrictive than that.
- 2048,
-
- // Keep low for sync.
- 512
-};
-
-const SettingsStorageQuotaEnforcer::Limits kLocalQuota = {
- // Same as localStorage (5MB).
- 5 * 1000 * 1024,
-
- // No need to be restrictive per key here.
- UINT_MAX,
-
- // Ditto.
- UINT_MAX
-};
-
// Settings change Observer which forwards changes on to the extension
// processes for |profile| and its incognito partner if it exists.
class DefaultObserver : public SettingsObserver {
@@ -109,6 +88,40 @@ void CallbackWithUnlimitedStorage(
callback.Run(&unlimited_storage);
}
+// Returns the integer at |path| in |dict| as a size_t, or a default value if
+// there's nothing found at that path.
+size_t GetStringAsInteger(
+ const DictionaryValue& dict, const std::string& path, size_t default_size) {
+ std::string as_string;
+ if (!dict.GetString(path, &as_string))
+ return default_size;
+ size_t as_integer = default_size;
+ CHECK(base::StringToSizeT(as_string, &as_integer));
+ return as_integer;
+}
+
+// Constructs a |Limits| configuration by looking up the QUOTA_BYTES,
+// QUOTA_BYTES_PER_ITEM, and MAX_ITEMS properties of a storage area defined
+// in chrome/common/extensions/api/storage.json (via ExtensionAPI).
+SettingsStorageQuotaEnforcer::Limits GetLimitsFromExtensionAPI(
+ const std::string& storage_area_id) {
+ const DictionaryValue* storage_schema =
+ ExtensionAPI::GetInstance()->GetSchema("storage");
+ CHECK(storage_schema);
+
+ DictionaryValue* properties = NULL;
+ storage_schema->GetDictionary(
+ "properties." + storage_area_id + ".properties", &properties);
+ CHECK(properties);
+
+ SettingsStorageQuotaEnforcer::Limits limits = {
+ GetStringAsInteger(*properties, "QUOTA_BYTES.value", UINT_MAX),
+ GetStringAsInteger(*properties, "QUOTA_BYTES_PER_ITEM.value", UINT_MAX),
+ GetStringAsInteger(*properties, "MAX_ITEMS.value", UINT_MAX),
+ };
+ return limits;
+}
+
} // namespace
// Ref-counted container for a SettingsBackend object.
@@ -214,7 +227,9 @@ SettingsFrontend* SettingsFrontend::Create(
SettingsFrontend::SettingsFrontend(
const scoped_refptr<SettingsStorageFactory>& factory, Profile* profile)
- : profile_(profile),
+ : local_quota_limit_(GetLimitsFromExtensionAPI("local")),
+ sync_quota_limit_(GetLimitsFromExtensionAPI("sync")),
+ profile_(profile),
observers_(new SettingsObserverList()),
profile_observer_(new DefaultObserver(profile)) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -226,28 +241,28 @@ SettingsFrontend::SettingsFrontend(
backends_[settings_namespace::LOCAL].app =
BackendWrapper::CreateAndInit(
factory,
- kLocalQuota,
+ local_quota_limit_,
observers_,
profile_path.AppendASCII(
ExtensionService::kLocalAppSettingsDirectoryName));
backends_[settings_namespace::LOCAL].extension =
BackendWrapper::CreateAndInit(
factory,
- kLocalQuota,
+ local_quota_limit_,
observers_,
profile_path.AppendASCII(
ExtensionService::kLocalExtensionSettingsDirectoryName));
backends_[settings_namespace::SYNC].app =
BackendWrapper::CreateAndInit(
factory,
- kSyncQuota,
+ sync_quota_limit_,
observers_,
profile_path.AppendASCII(
ExtensionService::kSyncAppSettingsDirectoryName));
backends_[settings_namespace::SYNC].extension =
BackendWrapper::CreateAndInit(
factory,
- kSyncQuota,
+ sync_quota_limit_,
observers_,
profile_path.AppendASCII(
ExtensionService::kSyncExtensionSettingsDirectoryName));
diff --git a/chrome/browser/extensions/settings/settings_frontend.h b/chrome/browser/extensions/settings/settings_frontend.h
index e007b9f..c651bb2 100644
--- a/chrome/browser/extensions/settings/settings_frontend.h
+++ b/chrome/browser/extensions/settings/settings_frontend.h
@@ -16,6 +16,7 @@
#include "chrome/browser/extensions/settings/settings_leveldb_storage.h"
#include "chrome/browser/extensions/settings/settings_namespace.h"
#include "chrome/browser/extensions/settings/settings_observer.h"
+#include "chrome/browser/extensions/settings/settings_storage_quota_enforcer.h"
#include "chrome/browser/sync/api/syncable_service.h"
class Profile;
@@ -29,9 +30,11 @@ class SettingsStorage;
// All public methods must be called on the UI thread.
class SettingsFrontend {
public:
- // Creates with the default factory. Ownership of |profile| not taken.
+ // Creates with the default factory. Ownership of |profile| not taken.
static SettingsFrontend* Create(Profile* profile);
+ // Creates with a specific factory |storage_factory| (presumably for tests).
+ // Ownership of |profile| not taken.
static SettingsFrontend* Create(
const scoped_refptr<SettingsStorageFactory>& storage_factory,
// Owership NOT taken.
@@ -67,6 +70,11 @@ class SettingsFrontend {
// Ownership NOT taken.
Profile* profile);
+ // The quota limit configurations for the local and sync areas, taken out of
+ // the schema in chrome/common/extensions/api/storage.json.
+ const SettingsStorageQuotaEnforcer::Limits local_quota_limit_;
+ const SettingsStorageQuotaEnforcer::Limits sync_quota_limit_;
+
// The (non-incognito) Profile this Frontend belongs to.
Profile* const profile_;
diff --git a/chrome/browser/extensions/settings/settings_leveldb_storage.cc b/chrome/browser/extensions/settings/settings_leveldb_storage.cc
index b768e29..c41d267 100644
--- a/chrome/browser/extensions/settings/settings_leveldb_storage.cc
+++ b/chrome/browser/extensions/settings/settings_leveldb_storage.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -95,6 +95,25 @@ SettingsLeveldbStorage::~SettingsLeveldbStorage() {
}
}
+size_t SettingsLeveldbStorage::GetBytesInUse(const std::string& key) {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
+size_t SettingsLeveldbStorage::GetBytesInUse(
+ const std::vector<std::string>& keys) {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
+size_t SettingsLeveldbStorage::GetBytesInUse() {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
SettingsStorage::ReadResult SettingsLeveldbStorage::Get(
const std::string& key) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
diff --git a/chrome/browser/extensions/settings/settings_leveldb_storage.h b/chrome/browser/extensions/settings/settings_leveldb_storage.h
index 04f2f2c..f458667 100644
--- a/chrome/browser/extensions/settings/settings_leveldb_storage.h
+++ b/chrome/browser/extensions/settings/settings_leveldb_storage.h
@@ -38,6 +38,9 @@ class SettingsLeveldbStorage : public SettingsStorage {
virtual ~SettingsLeveldbStorage();
// SettingsStorage implementation.
+ virtual size_t GetBytesInUse(const std::string& key) OVERRIDE;
+ virtual size_t GetBytesInUse(const std::vector<std::string>& keys) OVERRIDE;
+ virtual size_t GetBytesInUse() OVERRIDE;
virtual ReadResult Get(const std::string& key) OVERRIDE;
virtual ReadResult Get(const std::vector<std::string>& keys) OVERRIDE;
virtual ReadResult Get() OVERRIDE;
diff --git a/chrome/browser/extensions/settings/settings_quota_unittest.cc b/chrome/browser/extensions/settings/settings_quota_unittest.cc
index 0cb4c19..6314c47 100644
--- a/chrome/browser/extensions/settings/settings_quota_unittest.cc
+++ b/chrome/browser/extensions/settings/settings_quota_unittest.cc
@@ -49,10 +49,10 @@ class ExtensionSettingsQuotaTest : public testing::Test {
protected:
// Creates |storage_|. Must only be called once.
void CreateStorage(
- size_t quota_bytes, size_t quota_bytes_per_setting, size_t max_keys) {
+ size_t quota_bytes, size_t quota_bytes_per_item, size_t max_items) {
ASSERT_TRUE(storage_.get() == NULL);
SettingsStorageQuotaEnforcer::Limits limits =
- { quota_bytes, quota_bytes_per_setting, max_keys };
+ { quota_bytes, quota_bytes_per_item, max_items };
storage_.reset(new SettingsStorageQuotaEnforcer(limits, delegate_));
}
@@ -557,4 +557,39 @@ TEST_F(ExtensionSettingsQuotaTest,
EXPECT_TRUE(SettingsEqual(settings));
}
+TEST_F(ExtensionSettingsQuotaTest, GetBytesInUse) {
+ // Just testing GetBytesInUse, no need for a quota.
+ CreateStorage(UINT_MAX, UINT_MAX, UINT_MAX);
+
+ std::vector<std::string> ab;
+ ab.push_back("a");
+ ab.push_back("b");
+
+ EXPECT_EQ(0u, storage_->GetBytesInUse());
+ EXPECT_EQ(0u, storage_->GetBytesInUse("a"));
+ EXPECT_EQ(0u, storage_->GetBytesInUse("b"));
+ EXPECT_EQ(0u, storage_->GetBytesInUse(ab));
+
+ storage_->Set(DEFAULTS, "a", *byte_value_1_);
+
+ EXPECT_EQ(2u, storage_->GetBytesInUse());
+ EXPECT_EQ(2u, storage_->GetBytesInUse("a"));
+ EXPECT_EQ(0u, storage_->GetBytesInUse("b"));
+ EXPECT_EQ(2u, storage_->GetBytesInUse(ab));
+
+ storage_->Set(DEFAULTS, "b", *byte_value_1_);
+
+ EXPECT_EQ(4u, storage_->GetBytesInUse());
+ EXPECT_EQ(2u, storage_->GetBytesInUse("a"));
+ EXPECT_EQ(2u, storage_->GetBytesInUse("b"));
+ EXPECT_EQ(4u, storage_->GetBytesInUse(ab));
+
+ storage_->Set(DEFAULTS, "c", *byte_value_1_);
+
+ EXPECT_EQ(6u, storage_->GetBytesInUse());
+ EXPECT_EQ(2u, storage_->GetBytesInUse("a"));
+ EXPECT_EQ(2u, storage_->GetBytesInUse("b"));
+ EXPECT_EQ(4u, storage_->GetBytesInUse(ab));
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/settings/settings_storage.h b/chrome/browser/extensions/settings/settings_storage.h
index 4c5c674..51cc603 100644
--- a/chrome/browser/extensions/settings/settings_storage.h
+++ b/chrome/browser/extensions/settings/settings_storage.h
@@ -100,6 +100,15 @@ class SettingsStorage {
virtual ~SettingsStorage() {}
+ // Gets the amount of space being used by a single value, in bytes.
+ virtual size_t GetBytesInUse(const std::string& key) = 0;
+
+ // Gets the total amount of space being used by multiple values, in bytes.
+ virtual size_t GetBytesInUse(const std::vector<std::string>& keys) = 0;
+
+ // Gets the total amount of space being used by this storage area, in bytes.
+ virtual size_t GetBytesInUse() = 0;
+
// Gets a single value from storage.
virtual ReadResult Get(const std::string& key) = 0;
diff --git a/chrome/browser/extensions/settings/settings_storage_quota_enforcer.cc b/chrome/browser/extensions/settings/settings_storage_quota_enforcer.cc
index 788397a..d0f5ace 100644
--- a/chrome/browser/extensions/settings/settings_storage_quota_enforcer.cc
+++ b/chrome/browser/extensions/settings/settings_storage_quota_enforcer.cc
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
+#include "chrome/common/extensions/api/extension_api.h"
namespace extensions {
@@ -18,9 +19,9 @@ const char* kExceededQuotaErrorMessage = "Quota exceeded";
// Resources there are a quota for.
enum Resource {
- TOTAL_BYTES,
- BYTES_PER_SETTING,
- KEY_COUNT
+ QUOTA_BYTES,
+ QUOTA_BYTES_PER_ITEM,
+ MAX_ITEMS
};
// Allocates a setting in a record of total and per-setting usage.
@@ -54,15 +55,15 @@ void Free(
// Returns an error result and logs the quota exceeded to UMA.
SettingsStorage::WriteResult QuotaExceededFor(Resource resource) {
switch (resource) {
- case TOTAL_BYTES:
+ case QUOTA_BYTES:
UMA_HISTOGRAM_COUNTS_100(
"Extensions.SettingsQuotaExceeded.TotalBytes", 1);
break;
- case BYTES_PER_SETTING:
+ case QUOTA_BYTES_PER_ITEM:
UMA_HISTOGRAM_COUNTS_100(
"Extensions.SettingsQuotaExceeded.BytesPerSetting", 1);
break;
- case KEY_COUNT:
+ case MAX_ITEMS:
UMA_HISTOGRAM_COUNTS_100(
"Extensions.SettingsQuotaExceeded.KeyCount", 1);
break;
@@ -93,6 +94,28 @@ SettingsStorageQuotaEnforcer::SettingsStorageQuotaEnforcer(
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 SettingsStorage implementations rely on GetBytesInUse being
+ // implemented here.
+ return used_total_;
+}
+
SettingsStorage::ReadResult SettingsStorageQuotaEnforcer::Get(
const std::string& key) {
return delegate_->Get(key);
@@ -115,13 +138,13 @@ SettingsStorage::WriteResult SettingsStorageQuotaEnforcer::Set(
if (options != IGNORE_QUOTA) {
if (new_used_total > limits_.quota_bytes) {
- return QuotaExceededFor(TOTAL_BYTES);
+ return QuotaExceededFor(QUOTA_BYTES);
}
- if (new_used_per_setting[key] > limits_.quota_bytes_per_setting) {
- return QuotaExceededFor(BYTES_PER_SETTING);
+ if (new_used_per_setting[key] > limits_.quota_bytes_per_item) {
+ return QuotaExceededFor(QUOTA_BYTES_PER_ITEM);
}
- if (new_used_per_setting.size() > limits_.max_keys) {
- return QuotaExceededFor(KEY_COUNT);
+ if (new_used_per_setting.size() > limits_.max_items) {
+ return QuotaExceededFor(MAX_ITEMS);
}
}
@@ -143,17 +166,17 @@ SettingsStorage::WriteResult SettingsStorageQuotaEnforcer::Set(
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_setting) {
- return QuotaExceededFor(BYTES_PER_SETTING);
+ new_used_per_setting[it.key()] > limits_.quota_bytes_per_item) {
+ return QuotaExceededFor(QUOTA_BYTES_PER_ITEM);
}
}
if (options != IGNORE_QUOTA) {
if (new_used_total > limits_.quota_bytes) {
- return QuotaExceededFor(TOTAL_BYTES);
+ return QuotaExceededFor(QUOTA_BYTES);
}
- if (new_used_per_setting.size() > limits_.max_keys) {
- return QuotaExceededFor(KEY_COUNT);
+ if (new_used_per_setting.size() > limits_.max_items) {
+ return QuotaExceededFor(MAX_ITEMS);
}
}
diff --git a/chrome/browser/extensions/settings/settings_storage_quota_enforcer.h b/chrome/browser/extensions/settings/settings_storage_quota_enforcer.h
index 103a758..19ce704 100644
--- a/chrome/browser/extensions/settings/settings_storage_quota_enforcer.h
+++ b/chrome/browser/extensions/settings/settings_storage_quota_enforcer.h
@@ -17,14 +17,14 @@ namespace extensions {
class SettingsStorageQuotaEnforcer : public SettingsStorage {
public:
struct Limits {
- // The storage quota in bytes.
+ // The total quota in bytes.
size_t quota_bytes;
- // The quota per individual setting in bytes.
- size_t quota_bytes_per_setting;
+ // The quota for each individual item in bytes.
+ size_t quota_bytes_per_item;
- // The maximum number of settings keys allowed.
- size_t max_keys;
+ // The maximum number of items allowed.
+ size_t max_items;
};
SettingsStorageQuotaEnforcer(const Limits& limits, SettingsStorage* delegate);
@@ -32,6 +32,9 @@ class SettingsStorageQuotaEnforcer : public SettingsStorage {
virtual ~SettingsStorageQuotaEnforcer();
// SettingsStorage implementation.
+ virtual size_t GetBytesInUse(const std::string& key) OVERRIDE;
+ virtual size_t GetBytesInUse(const std::vector<std::string>& keys) OVERRIDE;
+ virtual size_t GetBytesInUse() OVERRIDE;
virtual ReadResult Get(const std::string& key) OVERRIDE;
virtual ReadResult Get(const std::vector<std::string>& keys) OVERRIDE;
virtual ReadResult Get() OVERRIDE;
@@ -52,11 +55,11 @@ class SettingsStorageQuotaEnforcer : public SettingsStorage {
// The delegate storage area.
scoped_ptr<SettingsStorage> const delegate_;
- // Total size of the settings currently being used. Includes both settings
- // keys and their JSON-encoded values.
+ // Total bytes in used by |delegate_|. Includes both key lengths and
+ // JSON-encoded values.
size_t used_total_;
- // Map of key to size of that key, including the key itself.
+ // Map of item key to its size, including the key itself.
std::map<std::string, size_t> used_per_setting_;
DISALLOW_COPY_AND_ASSIGN(SettingsStorageQuotaEnforcer);
diff --git a/chrome/browser/extensions/settings/syncable_settings_storage.cc b/chrome/browser/extensions/settings/syncable_settings_storage.cc
index f65d7e3..87a967a 100644
--- a/chrome/browser/extensions/settings/syncable_settings_storage.cc
+++ b/chrome/browser/extensions/settings/syncable_settings_storage.cc
@@ -32,6 +32,22 @@ SyncableSettingsStorage::~SyncableSettingsStorage() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
}
+size_t SyncableSettingsStorage::GetBytesInUse(const std::string& key) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ return delegate_->GetBytesInUse(key);
+}
+
+size_t SyncableSettingsStorage::GetBytesInUse(
+ const std::vector<std::string>& keys) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ return delegate_->GetBytesInUse(keys);
+}
+
+size_t SyncableSettingsStorage::GetBytesInUse() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ return delegate_->GetBytesInUse();
+}
+
SettingsStorage::ReadResult SyncableSettingsStorage::Get(
const std::string& key) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
diff --git a/chrome/browser/extensions/settings/syncable_settings_storage.h b/chrome/browser/extensions/settings/syncable_settings_storage.h
index d650229..8c8b1e0 100644
--- a/chrome/browser/extensions/settings/syncable_settings_storage.h
+++ b/chrome/browser/extensions/settings/syncable_settings_storage.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -31,6 +31,9 @@ class SyncableSettingsStorage : public SettingsStorage {
virtual ~SyncableSettingsStorage();
// SettingsStorage implementation.
+ virtual size_t GetBytesInUse(const std::string& key) OVERRIDE;
+ virtual size_t GetBytesInUse(const std::vector<std::string>& keys) OVERRIDE;
+ virtual size_t GetBytesInUse() OVERRIDE;
virtual ReadResult Get(const std::string& key) OVERRIDE;
virtual ReadResult Get(const std::vector<std::string>& keys) OVERRIDE;
virtual ReadResult Get() OVERRIDE;
diff --git a/chrome/browser/extensions/settings/testing_settings_storage.cc b/chrome/browser/extensions/settings/testing_settings_storage.cc
index fc78991..04981f9 100644
--- a/chrome/browser/extensions/settings/testing_settings_storage.cc
+++ b/chrome/browser/extensions/settings/testing_settings_storage.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -37,6 +37,25 @@ void TestingSettingsStorage::SetFailAllRequests(bool fail_all_requests) {
fail_all_requests_ = fail_all_requests;
}
+size_t TestingSettingsStorage::GetBytesInUse(const std::string& key) {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
+size_t TestingSettingsStorage::GetBytesInUse(
+ const std::vector<std::string>& keys) {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
+size_t TestingSettingsStorage::GetBytesInUse() {
+ // Let SettingsStorageQuotaEnforcer implement this.
+ NOTREACHED() << "Not implemented";
+ return 0;
+}
+
SettingsStorage::ReadResult TestingSettingsStorage::Get(
const std::string& key) {
return Get(CreateVector(key));
diff --git a/chrome/browser/extensions/settings/testing_settings_storage.h b/chrome/browser/extensions/settings/testing_settings_storage.h
index 9b6df40..21564c3 100644
--- a/chrome/browser/extensions/settings/testing_settings_storage.h
+++ b/chrome/browser/extensions/settings/testing_settings_storage.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -22,6 +22,9 @@ class TestingSettingsStorage : public SettingsStorage {
void SetFailAllRequests(bool fail_all_requests);
// SettingsStorage implementation.
+ virtual size_t GetBytesInUse(const std::string& key) OVERRIDE;
+ virtual size_t GetBytesInUse(const std::vector<std::string>& keys) OVERRIDE;
+ virtual size_t GetBytesInUse() OVERRIDE;
virtual ReadResult Get(const std::string& key) OVERRIDE;
virtual ReadResult Get(const std::vector<std::string>& keys) OVERRIDE;
virtual ReadResult Get() OVERRIDE;
diff --git a/chrome/browser/extensions/settings/weak_unlimited_settings_storage.cc b/chrome/browser/extensions/settings/weak_unlimited_settings_storage.cc
index c1232cb..3d04ab3 100644
--- a/chrome/browser/extensions/settings/weak_unlimited_settings_storage.cc
+++ b/chrome/browser/extensions/settings/weak_unlimited_settings_storage.cc
@@ -12,6 +12,20 @@ WeakUnlimitedSettingsStorage::WeakUnlimitedSettingsStorage(
WeakUnlimitedSettingsStorage::~WeakUnlimitedSettingsStorage() {}
+size_t WeakUnlimitedSettingsStorage::GetBytesInUse(const std::string& key) {
+ return delegate_->GetBytesInUse(key);
+}
+
+size_t WeakUnlimitedSettingsStorage::GetBytesInUse(
+ const std::vector<std::string>& keys) {
+ return delegate_->GetBytesInUse(keys);
+}
+
+
+size_t WeakUnlimitedSettingsStorage::GetBytesInUse() {
+ return delegate_->GetBytesInUse();
+}
+
SettingsStorage::ReadResult WeakUnlimitedSettingsStorage::Get(
const std::string& key) {
return delegate_->Get(key);
diff --git a/chrome/browser/extensions/settings/weak_unlimited_settings_storage.h b/chrome/browser/extensions/settings/weak_unlimited_settings_storage.h
index a453956..43cdf02 100644
--- a/chrome/browser/extensions/settings/weak_unlimited_settings_storage.h
+++ b/chrome/browser/extensions/settings/weak_unlimited_settings_storage.h
@@ -22,6 +22,9 @@ class WeakUnlimitedSettingsStorage : public SettingsStorage {
virtual ~WeakUnlimitedSettingsStorage();
// SettingsStorage implementation.
+ virtual size_t GetBytesInUse(const std::string& key) OVERRIDE;
+ virtual size_t GetBytesInUse(const std::vector<std::string>& keys) OVERRIDE;
+ virtual size_t GetBytesInUse() OVERRIDE;
virtual ReadResult Get(const std::string& key) OVERRIDE;
virtual ReadResult Get(const std::vector<std::string>& keys) OVERRIDE;
virtual ReadResult Get() OVERRIDE;
diff --git a/chrome/common/extensions/api/storage.json b/chrome/common/extensions/api/storage.json
index a52e217..63309bb 100644
--- a/chrome/common/extensions/api/storage.json
+++ b/chrome/common/extensions/api/storage.json
@@ -19,7 +19,7 @@
}
},
{
- "id": "StorageNamespace",
+ "id": "StorageArea",
"type": "object",
"functions": [
{
@@ -40,7 +40,7 @@
"additionalProperties": { "type": "any" }
}
],
- "description": "A single key to get, list of keys to get, or a dictionary specifying default values (see description of the object). An empty list or object will return an empty result object. Pass in null or undefined to get the entire contents of storage; this should only be used for debugging.",
+ "description": "A single key to get, list of keys to get, or a dictionary specifying default values (see description of the object). An empty list or object will return an empty result object. Pass in <code>null</code> to get the entire contents of storage.",
"optional": true
},
{
@@ -60,6 +60,35 @@
]
},
{
+ "name": "getBytesInUse",
+ "unprivileged": true,
+ "type": "function",
+ "description": "Gets the amount of space (in bytes) being used by one or more items.",
+ "parameters": [
+ {
+ "name": "keys",
+ "choices": [
+ { "type": "string" },
+ { "type": "array", "items": { "type": "string" } }
+ ],
+ "description": "A single key or list of keys to get the total usage for. An empty list will return 0. Pass in <code>null</code> to get the total usage of all of storage.",
+ "optional": true
+ },
+ {
+ "name": "callback",
+ "type": "function",
+ "description": "Callback with the amount of space being used by storage, or on failure (in which case lastError will be set).",
+ "parameters": [
+ {
+ "name": "bytesInUse",
+ "type": "integer",
+ "description": "Amount of space being used in storage, in bytes."
+ }
+ ]
+ }
+ ]
+ },
+ {
"name": "set",
"unprivileged": true,
"type": "function",
@@ -146,16 +175,44 @@
],
"properties": {
"sync": {
- "$ref": "StorageNamespace",
+ "$ref": "StorageArea",
"description": "Items under the \"sync\" namespace are synced using Chrome Sync.",
"unprivileged": true,
- "value": [ "sync" ]
+ "value": [ "sync" ],
+ "properties": {
+ "QUOTA_BYTES": {
+ "type": "integer",
+ "value": "102400",
+ "unprivileged": true,
+ "description": "The maximum total amount (in bytes) of data that can be stored in sync storage."
+ },
+ "QUOTA_BYTES_PER_ITEM": {
+ "type": "integer",
+ "value": "2048",
+ "unprivileged": true,
+ "description": "The maximum size (in bytes) of each individual item in sync storage."
+ },
+ "MAX_ITEMS": {
+ "type": "integer",
+ "value": "512",
+ "unprivileged": true,
+ "description": "The maximum number of items that can be stored in sync storage."
+ }
+ }
},
"local": {
- "$ref": "StorageNamespace",
+ "$ref": "StorageArea",
"description": "Items under the \"local\" namespace are local to each machine.",
"unprivileged": true,
- "value": [ "local" ]
+ "value": [ "local" ],
+ "properties": {
+ "QUOTA_BYTES": {
+ "type": "integer",
+ "value": "5120000",
+ "unprivileged": true,
+ "description": "The maximum amount (in bytes) of data that can be stored in local storage. This value may be ignored if the extension has the <code>unlimitedStorage</code> permission."
+ }
+ }
}
}
}
diff --git a/chrome/common/extensions/docs/storage.html b/chrome/common/extensions/docs/storage.html
index a891f34..e97c896 100644
--- a/chrome/common/extensions/docs/storage.html
+++ b/chrome/common/extensions/docs/storage.html
@@ -378,19 +378,21 @@
</li>
</ol>
</li><li>
- <a href="#type-StorageNamespace">StorageNamespace</a>
+ <a href="#type-StorageArea">StorageArea</a>
<ol>
<li>
- <a href="#global-StorageNamespace-methods">Methods</a>
+ <a href="#global-StorageArea-methods">Methods</a>
<ol>
<li>
- <a href="#method-StorageNamespace-clear">clear</a>
+ <a href="#method-StorageArea-clear">clear</a>
</li><li>
- <a href="#method-StorageNamespace-get">get</a>
+ <a href="#method-StorageArea-get">get</a>
</li><li>
- <a href="#method-StorageNamespace-remove">remove</a>
+ <a href="#method-StorageArea-getBytesInUse">getBytesInUse</a>
</li><li>
- <a href="#method-StorageNamespace-set">set</a>
+ <a href="#method-StorageArea-remove">remove</a>
+ </li><li>
+ <a href="#method-StorageArea-set">set</a>
</li>
</ol>
</li>
@@ -449,7 +451,7 @@
<span class="enum" style="display: none; ">enumerated</span>
<span id="typeTemplate">
<span>
- <a href="storage.html#type-StorageNamespace">StorageNamespace</a>
+ <a href="storage.html#type-StorageArea">StorageArea</a>
</span>
<span style="display: none; ">
<span>
@@ -523,7 +525,7 @@
<span class="enum" style="display: none; ">enumerated</span>
<span id="typeTemplate">
<span>
- <a href="storage.html#type-StorageNamespace">StorageNamespace</a>
+ <a href="storage.html#type-StorageArea">StorageArea</a>
</span>
<span style="display: none; ">
<span>
@@ -1059,8 +1061,8 @@
</div>
</div><div class="apiItem">
- <a name="type-StorageNamespace"></a>
- <h4>StorageNamespace</h4>
+ <a name="type-StorageArea"></a>
+ <h4>StorageArea</h4>
<div>
<dt>
@@ -1118,17 +1120,17 @@
<!-- OBJECT METHODS -->
<dd>
<div class="apiGroup" style="">
- <a name="global-StorageNamespace-methods"></a>
- <h3>Methods of StorageNamespace</h3>
+ <a name="global-StorageArea-methods"></a>
+ <h3>Methods of StorageArea</h3>
<!-- iterates over all functions -->
<div class="apiItem">
- <a name="method-StorageNamespace-clear"></a> <!-- method-anchor -->
+ <a name="method-StorageArea-clear"></a> <!-- method-anchor -->
<h4>clear</h4>
<div class="summary"><span style="display: none; ">void</span>
<!-- Note: intentionally longer 80 columns -->
- <span>storageNamespace.clear</span>(<span class="optional"><span style="display: none; ">, </span><span>function</span>
+ <span>storageArea.clear</span>(<span class="optional"><span style="display: none; ">, </span><span>function</span>
<var><span>callback</span></var></span>)</div>
<div class="description">
@@ -1252,12 +1254,12 @@
</div> <!-- /description -->
</div><div class="apiItem">
- <a name="method-StorageNamespace-get"></a> <!-- method-anchor -->
+ <a name="method-StorageArea-get"></a> <!-- method-anchor -->
<h4>get</h4>
<div class="summary"><span style="display: none; ">void</span>
<!-- Note: intentionally longer 80 columns -->
- <span>storageNamespace.get</span>(<span class="optional"><span style="display: none; ">, </span><span>string or array of string or object</span>
+ <span>storageArea.get</span>(<span class="optional"><span style="display: none; ">, </span><span>string or array of string or object</span>
<var><span>keys</span></var></span><span class="null"><span>, </span><span>function</span>
<var><span>callback</span></var></span>)</div>
@@ -1299,7 +1301,7 @@
<dd class="todo" style="display: none; ">
Undocumented.
</dd>
- <dd>A single key to get, list of keys to get, or a dictionary specifying default values (see description of the object). An empty list or object will return an empty result object. Pass in null or undefined to get the entire contents of storage; this should only be used for debugging.</dd>
+ <dd>A single key to get, list of keys to get, or a dictionary specifying default values (see description of the object). An empty list or object will return an empty result object. Pass in <code>null</code> to get the entire contents of storage.</dd>
<dd style="display: none; ">
This parameter was added in version
<b><span></span></b>.
@@ -1515,12 +1517,275 @@
</div> <!-- /description -->
</div><div class="apiItem">
- <a name="method-StorageNamespace-remove"></a> <!-- method-anchor -->
+ <a name="method-StorageArea-getBytesInUse"></a> <!-- method-anchor -->
+ <h4>getBytesInUse</h4>
+
+ <div class="summary"><span style="display: none; ">void</span>
+ <!-- Note: intentionally longer 80 columns -->
+ <span>storageArea.getBytesInUse</span>(<span class="optional"><span style="display: none; ">, </span><span>string or array of string</span>
+ <var><span>keys</span></var></span><span class="null"><span>, </span><span>function</span>
+ <var><span>callback</span></var></span>)</div>
+
+ <div class="description">
+ <p class="todo" style="display: none; ">Undocumented.</p>
+ <p>Gets the amount of space (in bytes) being used by one or more items.</p>
+
+ <!-- PARAMETERS -->
+ <h4>Parameters</h4>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>keys</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional">optional</span>
+ <span class="enum" style="display: none; ">enumerated</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>string or array of string</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>A single key or list of keys to get the total usage for. An empty list will return 0. Pass in <code>null</code> to get the total usage of all of storage.</dd>
+ <dd style="display: none; ">
+ This parameter was added in version
+ <b><span></span></b>.
+ You must omit this parameter in earlier versions,
+ and you may omit it in any version. If you require this
+ parameter, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd style="display: none; ">
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </dd>
+
+ <!-- OBJECT METHODS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ <!-- OBJECT EVENT FIELDS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ <!-- FUNCTION PARAMETERS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ </div>
+ </div><div>
+ <div>
+ <dt>
+ <var>callback</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional" style="display: none; ">optional</span>
+ <span class="enum" style="display: none; ">enumerated</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>function</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>Callback with the amount of space being used by storage, or on failure (in which case lastError will be set).</dd>
+ <dd style="display: none; ">
+ This parameter was added in version
+ <b><span></span></b>.
+ You must omit this parameter in earlier versions,
+ and you may omit it in any version. If you require this
+ parameter, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd style="display: none; ">
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </dd>
+
+ <!-- OBJECT METHODS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ <!-- OBJECT EVENT FIELDS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ <!-- FUNCTION PARAMETERS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ </div>
+ </div>
+ </dl>
+
+ <!-- RETURNS -->
+ <h4 style="display: none; ">Returns</h4>
+ <dl>
+ <div style="display: none; ">
+ <div>
+ </div>
+ </div>
+ </dl>
+
+ <!-- CALLBACK -->
+ <div>
+ <div>
+ <h4>Callback function</h4>
+ <p>
+ The callback <em>parameter</em> should specify a function
+ that looks like this:
+ </p>
+ <p style="display: none; ">
+ If you specify the <em>callback</em> parameter, it should
+ specify a function that looks like this:
+ </p>
+
+ <!-- Note: intentionally longer 80 columns -->
+ <pre>function(<span>integer bytesInUse</span>) <span class="subdued">{...}</span>;</pre>
+ <dl>
+ <div>
+ <div>
+ <dt>
+ <var>bytesInUse</var>
+ <em>
+
+ <!-- TYPE -->
+ <div style="display:inline">
+ (
+ <span class="optional" style="display: none; ">optional</span>
+ <span class="enum" style="display: none; ">enumerated</span>
+ <span id="typeTemplate">
+ <span style="display: none; ">
+ <a> Type</a>
+ </span>
+ <span>
+ <span style="display: none; ">
+ array of <span><span></span></span>
+ </span>
+ <span>integer</span>
+ <span style="display: none; "></span>
+ </span>
+ </span>
+ )
+ </div>
+
+ </em>
+ </dt>
+ <dd class="todo" style="display: none; ">
+ Undocumented.
+ </dd>
+ <dd>Amount of space being used in storage, in bytes.</dd>
+ <dd style="display: none; ">
+ This parameter was added in version
+ <b><span></span></b>.
+ You must omit this parameter in earlier versions,
+ and you may omit it in any version. If you require this
+ parameter, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </dd>
+
+ <!-- OBJECT PROPERTIES -->
+ <dd style="display: none; ">
+ <dl>
+ <div>
+ <div>
+ </div>
+ </div>
+ </dl>
+ </dd>
+
+ <!-- OBJECT METHODS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ <!-- OBJECT EVENT FIELDS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ <!-- FUNCTION PARAMETERS -->
+ <dd style="display: none; ">
+ <div></div>
+ </dd>
+
+ </div>
+ </div>
+ </dl>
+ </div>
+ </div>
+
+ <!-- MIN_VERSION -->
+ <p style="display: none; ">
+ This function was added in version <b><span></span></b>.
+ If you require this function, the manifest key
+ <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
+ can ensure that your extension won't be run in an earlier browser version.
+ </p>
+ </div> <!-- /description -->
+
+ </div><div class="apiItem">
+ <a name="method-StorageArea-remove"></a> <!-- method-anchor -->
<h4>remove</h4>
<div class="summary"><span style="display: none; ">void</span>
<!-- Note: intentionally longer 80 columns -->
- <span>storageNamespace.remove</span>(<span class="null"><span style="display: none; ">, </span><span>string or array of string</span>
+ <span>storageArea.remove</span>(<span class="null"><span style="display: none; ">, </span><span>string or array of string</span>
<var><span>keys</span></var></span><span class="optional"><span>, </span><span>function</span>
<var><span>callback</span></var></span>)</div>
@@ -1713,12 +1978,12 @@
</div> <!-- /description -->
</div><div class="apiItem">
- <a name="method-StorageNamespace-set"></a> <!-- method-anchor -->
+ <a name="method-StorageArea-set"></a> <!-- method-anchor -->
<h4>set</h4>
<div class="summary"><span style="display: none; ">void</span>
<!-- Note: intentionally longer 80 columns -->
- <span>storageNamespace.set</span>(<span class="null"><span style="display: none; ">, </span><span>object</span>
+ <span>storageArea.set</span>(<span class="null"><span style="display: none; ">, </span><span>object</span>
<var><span>items</span></var></span><span class="optional"><span>, </span><span>function</span>
<var><span>callback</span></var></span>)</div>
diff --git a/chrome/renderer/resources/extensions/schema_generated_bindings.js b/chrome/renderer/resources/extensions/schema_generated_bindings.js
index 4134762..32c7701 100644
--- a/chrome/renderer/resources/extensions/schema_generated_bindings.js
+++ b/chrome/renderer/resources/extensions/schema_generated_bindings.js
@@ -493,6 +493,8 @@ var chrome = chrome || {};
// the constructor.
value = { __proto__: constructor.prototype };
constructor.apply(value, args);
+ // Recursively add properties.
+ addProperties(value, property);
} else if (property.type === 'object') {
// Recursively add properties.
addProperties(value, property);
diff --git a/chrome/renderer/resources/extensions/storage_custom_bindings.js b/chrome/renderer/resources/extensions/storage_custom_bindings.js
index cd58774..1d358c2 100644
--- a/chrome/renderer/resources/extensions/storage_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/storage_custom_bindings.js
@@ -10,8 +10,7 @@ native function GetChromeHidden();
var chromeHidden = GetChromeHidden();
-chromeHidden.registerCustomType('StorageNamespace',
- function(typesAPI) {
+chromeHidden.registerCustomType('StorageArea', function(typesAPI) {
var sendRequest = typesAPI.sendRequest;
function extendSchema(schema) {
@@ -20,7 +19,7 @@ chromeHidden.registerCustomType('StorageNamespace',
return extendedSchema;
}
- function StorageNamespace(namespace, schema) {
+ function StorageArea(namespace, schema) {
// Binds an API function for a namespace to its browser-side call, e.g.
// storage.sync.get('foo') -> (binds to) ->
// storage.get('sync', 'foo').
@@ -38,10 +37,11 @@ chromeHidden.registerCustomType('StorageNamespace',
extendSchema(schema));
};
}
- ['get', 'set', 'remove', 'clear'].forEach(bindApiFunction.bind(this));
+ var apiFunctions = ['get', 'set', 'remove', 'clear', 'getBytesInUse'];
+ apiFunctions.forEach(bindApiFunction.bind(this));
}
- return StorageNamespace;
+ return StorageArea;
});
})();
diff --git a/chrome/test/data/extensions/api_test/settings/simple_test/background.js b/chrome/test/data/extensions/api_test/settings/simple_test/background.js
index 85f5e62..7263286 100644
--- a/chrome/test/data/extensions/api_test/settings/simple_test/background.js
+++ b/chrome/test/data/extensions/api_test/settings/simple_test/background.js
@@ -291,12 +291,55 @@ chrome.test.runTests([
test(stage0);
},
+
+ function quota() {
+ // Just check that the constants are defined; no need to be forced to
+ // update them here as well if/when they change.
+ chrome.test.assertTrue(chrome.storage.sync.QUOTA_BYTES > 0);
+ chrome.test.assertTrue(chrome.storage.sync.QUOTA_BYTES_PER_ITEM > 0);
+ chrome.test.assertTrue(chrome.storage.sync.MAX_ITEMS > 0);
+
+ chrome.test.assertTrue(chrome.storage.local.QUOTA_BYTES > 0);
+ chrome.test.assertEq('undefined',
+ typeof chrome.storage.local.QUOTA_BYTES_PER_ITEM);
+ chrome.test.assertEq('undefined',
+ typeof chrome.storage.local.MAX_ITEMS);
+
+ var area = chrome.storage.sync;
+ function stage0() {
+ area.getBytesInUse(null, stage1);
+ }
+ function stage1(bytesInUse) {
+ chrome.test.assertEq(0, bytesInUse);
+ area.set({ a: 42, b: 43, c: 44 }, stage2);
+ }
+ function stage2() {
+ area.getBytesInUse(null, stage3);
+ }
+ function stage3(bytesInUse) {
+ chrome.test.assertEq(9, bytesInUse);
+ area.getBytesInUse('a', stage4);
+ }
+ function stage4(bytesInUse) {
+ chrome.test.assertEq(3, bytesInUse);
+ area.getBytesInUse(['a', 'b'], stage5);
+ }
+ function stage5(bytesInUse) {
+ chrome.test.assertEq(6, bytesInUse);
+ chrome.test.succeed();
+ }
+ area.clear(stage0);
+ },
+
+ // NOTE: throttling test must come last, since each test runs with a single
+ // quota.
function throttling() {
// We can only really test one of the namespaces since they will all get
// throttled together.
var api = chrome.storage.sync;
- // Should get throttled after 1000 calls.
+ // Should get throttled after 1000 calls (though in reality will be fewer
+ // due to previous tests).
var maxRequests = 1001;
function next() {
@@ -310,4 +353,5 @@ chrome.test.runTests([
}
api.clear(next);
}
+
]);