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

Side by Side Diff: chrome/browser/extensions/settings/settings_storage_quota_enforcer.cc

Issue 9284013: Extension Storage API: expose storage quota information to extensions, via: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 11 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 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/settings/settings_storage_quota_enforcer.h" 5 #include "chrome/browser/extensions/settings/settings_storage_quota_enforcer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/json/json_writer.h" 8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 12
13 namespace extensions { 13 namespace extensions {
14 14
15 namespace { 15 namespace {
16 16
17 const char* kExceededQuotaErrorMessage = "Quota exceeded"; 17 const char* kExceededQuotaErrorMessage = "Quota exceeded";
18 18
19 // Resources there are a quota for. 19 // Resources there are a quota for.
20 enum Resource { 20 enum Resource {
21 TOTAL_BYTES, 21 QUOTA_BYTES,
22 BYTES_PER_SETTING, 22 QUOTA_BYTES_PER_ITEM,
23 KEY_COUNT 23 MAX_ITEMS
24 }; 24 };
25 25
26 // Allocates a setting in a record of total and per-setting usage. 26 // Allocates a setting in a record of total and per-setting usage.
27 void Allocate( 27 void Allocate(
28 const std::string& key, 28 const std::string& key,
29 const Value& value, 29 const Value& value,
30 size_t* used_total, 30 size_t* used_total,
31 std::map<std::string, size_t>* used_per_setting) { 31 std::map<std::string, size_t>* used_per_setting) {
32 // Calculate the setting size based on its JSON serialization size. 32 // Calculate the setting size based on its JSON serialization size.
33 // TODO(kalman): Does this work with different encodings? 33 // TODO(kalman): Does this work with different encodings?
(...skipping 13 matching lines...) Expand all
47 size_t* used_total, 47 size_t* used_total,
48 std::map<std::string, size_t>* used_per_setting, 48 std::map<std::string, size_t>* used_per_setting,
49 const std::string& key) { 49 const std::string& key) {
50 *used_total -= (*used_per_setting)[key]; 50 *used_total -= (*used_per_setting)[key];
51 used_per_setting->erase(key); 51 used_per_setting->erase(key);
52 } 52 }
53 53
54 // Returns an error result and logs the quota exceeded to UMA. 54 // Returns an error result and logs the quota exceeded to UMA.
55 SettingsStorage::WriteResult QuotaExceededFor(Resource resource) { 55 SettingsStorage::WriteResult QuotaExceededFor(Resource resource) {
56 switch (resource) { 56 switch (resource) {
57 case TOTAL_BYTES: 57 case QUOTA_BYTES:
58 UMA_HISTOGRAM_COUNTS_100( 58 UMA_HISTOGRAM_COUNTS_100(
59 "Extensions.SettingsQuotaExceeded.TotalBytes", 1); 59 "Extensions.SettingsQuotaExceeded.TotalBytes", 1);
60 break; 60 break;
61 case BYTES_PER_SETTING: 61 case QUOTA_BYTES_PER_ITEM:
62 UMA_HISTOGRAM_COUNTS_100( 62 UMA_HISTOGRAM_COUNTS_100(
63 "Extensions.SettingsQuotaExceeded.BytesPerSetting", 1); 63 "Extensions.SettingsQuotaExceeded.BytesPerSetting", 1);
64 break; 64 break;
65 case KEY_COUNT: 65 case MAX_ITEMS:
66 UMA_HISTOGRAM_COUNTS_100( 66 UMA_HISTOGRAM_COUNTS_100(
67 "Extensions.SettingsQuotaExceeded.KeyCount", 1); 67 "Extensions.SettingsQuotaExceeded.KeyCount", 1);
68 break; 68 break;
69 default: 69 default:
70 NOTREACHED(); 70 NOTREACHED();
71 } 71 }
72 return SettingsStorage::WriteResult(kExceededQuotaErrorMessage); 72 return SettingsStorage::WriteResult(kExceededQuotaErrorMessage);
73 } 73 }
74 74
75 } // namespace 75 } // namespace
(...skipping 10 matching lines...) Expand all
86 86
87 for (DictionaryValue::Iterator it(maybe_settings.settings()); it.HasNext(); 87 for (DictionaryValue::Iterator it(maybe_settings.settings()); it.HasNext();
88 it.Advance()) { 88 it.Advance()) {
89 Allocate( 89 Allocate(
90 it.key(), it.value(), &used_total_, &used_per_setting_); 90 it.key(), it.value(), &used_total_, &used_per_setting_);
91 } 91 }
92 } 92 }
93 93
94 SettingsStorageQuotaEnforcer::~SettingsStorageQuotaEnforcer() {} 94 SettingsStorageQuotaEnforcer::~SettingsStorageQuotaEnforcer() {}
95 95
96 size_t SettingsStorageQuotaEnforcer::GetBytesInUse(const std::string& key) {
97 std::map<std::string, size_t>::iterator maybe_used =
98 used_per_setting_.find(key);
99 return maybe_used == used_per_setting_.end() ? 0u : maybe_used->second;
100 }
101
102 size_t SettingsStorageQuotaEnforcer::GetBytesInUse(
103 const std::vector<std::string>& keys) {
104 size_t used = 0;
105 for (std::vector<std::string>::const_iterator it = keys.begin();
106 it != keys.end(); ++it) {
107 used += it->second;
Matt Perry 2012/01/25 00:14:17 ? Don't you need to look this up in used_per_setti
not at google - send to devlin 2012/01/25 00:31:49 Oh crap. Drive by "oh why did I write it that way
108 }
109 return used;
110 }
111
112 size_t SettingsStorageQuotaEnforcer::GetBytesInUse() {
113 // All SettingsStorage implementations rely on GetBytesInUse being
114 // implemented here.
115 return used_total_;
116 }
117
96 SettingsStorage::ReadResult SettingsStorageQuotaEnforcer::Get( 118 SettingsStorage::ReadResult SettingsStorageQuotaEnforcer::Get(
97 const std::string& key) { 119 const std::string& key) {
98 return delegate_->Get(key); 120 return delegate_->Get(key);
99 } 121 }
100 122
101 SettingsStorage::ReadResult SettingsStorageQuotaEnforcer::Get( 123 SettingsStorage::ReadResult SettingsStorageQuotaEnforcer::Get(
102 const std::vector<std::string>& keys) { 124 const std::vector<std::string>& keys) {
103 return delegate_->Get(keys); 125 return delegate_->Get(keys);
104 } 126 }
105 127
106 SettingsStorage::ReadResult SettingsStorageQuotaEnforcer::Get() { 128 SettingsStorage::ReadResult SettingsStorageQuotaEnforcer::Get() {
107 return delegate_->Get(); 129 return delegate_->Get();
108 } 130 }
109 131
110 SettingsStorage::WriteResult SettingsStorageQuotaEnforcer::Set( 132 SettingsStorage::WriteResult SettingsStorageQuotaEnforcer::Set(
111 WriteOptions options, const std::string& key, const Value& value) { 133 WriteOptions options, const std::string& key, const Value& value) {
112 size_t new_used_total = used_total_; 134 size_t new_used_total = used_total_;
113 std::map<std::string, size_t> new_used_per_setting = used_per_setting_; 135 std::map<std::string, size_t> new_used_per_setting = used_per_setting_;
114 Allocate(key, value, &new_used_total, &new_used_per_setting); 136 Allocate(key, value, &new_used_total, &new_used_per_setting);
115 137
116 if (options != IGNORE_QUOTA) { 138 if (options != IGNORE_QUOTA) {
117 if (new_used_total > limits_.quota_bytes) { 139 if (new_used_total > limits_.quota_bytes) {
118 return QuotaExceededFor(TOTAL_BYTES); 140 return QuotaExceededFor(QUOTA_BYTES);
119 } 141 }
120 if (new_used_per_setting[key] > limits_.quota_bytes_per_setting) { 142 if (new_used_per_setting[key] > limits_.quota_bytes_per_item) {
121 return QuotaExceededFor(BYTES_PER_SETTING); 143 return QuotaExceededFor(QUOTA_BYTES_PER_ITEM);
122 } 144 }
123 if (new_used_per_setting.size() > limits_.max_keys) { 145 if (new_used_per_setting.size() > limits_.max_items) {
124 return QuotaExceededFor(KEY_COUNT); 146 return QuotaExceededFor(MAX_ITEMS);
125 } 147 }
126 } 148 }
127 149
128 WriteResult result = delegate_->Set(options, key, value); 150 WriteResult result = delegate_->Set(options, key, value);
129 if (result.HasError()) { 151 if (result.HasError()) {
130 return result; 152 return result;
131 } 153 }
132 154
133 used_total_ = new_used_total; 155 used_total_ = new_used_total;
134 used_per_setting_.swap(new_used_per_setting); 156 used_per_setting_.swap(new_used_per_setting);
135 return result; 157 return result;
136 } 158 }
137 159
138 SettingsStorage::WriteResult SettingsStorageQuotaEnforcer::Set( 160 SettingsStorage::WriteResult SettingsStorageQuotaEnforcer::Set(
139 WriteOptions options, const DictionaryValue& values) { 161 WriteOptions options, const DictionaryValue& values) {
140 size_t new_used_total = used_total_; 162 size_t new_used_total = used_total_;
141 std::map<std::string, size_t> new_used_per_setting = used_per_setting_; 163 std::map<std::string, size_t> new_used_per_setting = used_per_setting_;
142 for (DictionaryValue::Iterator it(values); it.HasNext(); it.Advance()) { 164 for (DictionaryValue::Iterator it(values); it.HasNext(); it.Advance()) {
143 Allocate(it.key(), it.value(), &new_used_total, &new_used_per_setting); 165 Allocate(it.key(), it.value(), &new_used_total, &new_used_per_setting);
144 166
145 if (options != IGNORE_QUOTA && 167 if (options != IGNORE_QUOTA &&
146 new_used_per_setting[it.key()] > limits_.quota_bytes_per_setting) { 168 new_used_per_setting[it.key()] > limits_.quota_bytes_per_item) {
147 return QuotaExceededFor(BYTES_PER_SETTING); 169 return QuotaExceededFor(QUOTA_BYTES_PER_ITEM);
148 } 170 }
149 } 171 }
150 172
151 if (options != IGNORE_QUOTA) { 173 if (options != IGNORE_QUOTA) {
152 if (new_used_total > limits_.quota_bytes) { 174 if (new_used_total > limits_.quota_bytes) {
153 return QuotaExceededFor(TOTAL_BYTES); 175 return QuotaExceededFor(QUOTA_BYTES);
154 } 176 }
155 if (new_used_per_setting.size() > limits_.max_keys) { 177 if (new_used_per_setting.size() > limits_.max_items) {
156 return QuotaExceededFor(KEY_COUNT); 178 return QuotaExceededFor(MAX_ITEMS);
157 } 179 }
158 } 180 }
159 181
160 WriteResult result = delegate_->Set(options, values); 182 WriteResult result = delegate_->Set(options, values);
161 if (result.HasError()) { 183 if (result.HasError()) {
162 return result; 184 return result;
163 } 185 }
164 186
165 used_total_ = new_used_total; 187 used_total_ = new_used_total;
166 used_per_setting_ = new_used_per_setting; 188 used_per_setting_ = new_used_per_setting;
(...skipping 30 matching lines...) Expand all
197 return result; 219 return result;
198 } 220 }
199 221
200 while (!used_per_setting_.empty()) { 222 while (!used_per_setting_.empty()) {
201 Free(&used_total_, &used_per_setting_, used_per_setting_.begin()->first); 223 Free(&used_total_, &used_per_setting_, used_per_setting_.begin()->first);
202 } 224 }
203 return result; 225 return result;
204 } 226 }
205 227
206 } // namespace extensions 228 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698