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

Side by Side Diff: chrome/browser/extensions/api/storage/storage_api.cc

Issue 11826048: Revert 176015 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/storage/storage_api.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/stringprintf.h"
12 #include "base/values.h"
13 #include "chrome/browser/extensions/api/storage/settings_frontend.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/extensions_quota_service.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/extensions/api/storage.h"
18 #include "content/public/browser/browser_thread.h"
19
20 namespace extensions {
21
22 using content::BrowserThread;
23
24 namespace {
25 const char kUnsupportedArgumentType[] = "Unsupported argument type";
26 const char kInvalidNamespaceErrorMessage[] =
27 "\"%s\" is not available in this instance of Chrome";
28 const char kManagedNamespaceDisabledErrorMessage[] =
29 "\"managed\" is disabled. Use \"--%s\" to enable it.";
30 const char kStorageErrorMessage[] = "Storage error";
31 } // namespace
32
33 // SettingsFunction
34
35 SettingsFunction::SettingsFunction()
36 : settings_namespace_(settings_namespace::INVALID) {}
37
38 SettingsFunction::~SettingsFunction() {}
39
40 bool SettingsFunction::ShouldSkipQuotaLimiting() const {
41 // Only apply quota if this is for sync storage.
42 std::string settings_namespace_string;
43 if (!args_->GetString(0, &settings_namespace_string)) {
44 // This is an error but it will be caught in RunImpl(), there is no
45 // mechanism to signify an error from this function.
46 return false;
47 }
48 return settings_namespace_string != "sync";
49 }
50
51 bool SettingsFunction::RunImpl() {
52 std::string settings_namespace_string;
53 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &settings_namespace_string));
54 args_->Remove(0, NULL);
55 settings_namespace_ =
56 settings_namespace::FromString(settings_namespace_string);
57 EXTENSION_FUNCTION_VALIDATE(
58 settings_namespace_ != settings_namespace::INVALID);
59
60 SettingsFrontend* frontend =
61 profile()->GetExtensionService()->settings_frontend();
62 if (!frontend->IsStorageEnabled(settings_namespace_)) {
63 error_ = base::StringPrintf(kInvalidNamespaceErrorMessage,
64 settings_namespace_string.c_str());
65 return false;
66 }
67
68 observers_ = frontend->GetObservers();
69 frontend->RunWithStorage(
70 extension_id(),
71 settings_namespace_,
72 base::Bind(&SettingsFunction::AsyncRunWithStorage, this));
73 return true;
74 }
75
76 void SettingsFunction::AsyncRunWithStorage(ValueStore* storage) {
77 bool success = RunWithStorage(storage);
78 BrowserThread::PostTask(
79 BrowserThread::UI,
80 FROM_HERE,
81 base::Bind(&SettingsFunction::SendResponse, this, success));
82 }
83
84 bool SettingsFunction::UseReadResult(ValueStore::ReadResult result) {
85 if (result->HasError()) {
86 error_ = result->error();
87 return false;
88 }
89
90 SetResult(result->settings().release());
91 return true;
92 }
93
94 bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result) {
95 if (result->HasError()) {
96 error_ = result->error();
97 return false;
98 }
99
100 if (!result->changes().empty()) {
101 observers_->Notify(
102 &SettingsObserver::OnSettingsChanged,
103 extension_id(),
104 settings_namespace_,
105 ValueStoreChange::ToJson(result->changes()));
106 }
107
108 return true;
109 }
110
111 // Concrete settings functions
112
113 namespace {
114
115 // Adds all StringValues from a ListValue to a vector of strings.
116 void AddAllStringValues(const ListValue& from, std::vector<std::string>* to) {
117 DCHECK(to->empty());
118 std::string as_string;
119 for (ListValue::const_iterator it = from.begin(); it != from.end(); ++it) {
120 if ((*it)->GetAsString(&as_string)) {
121 to->push_back(as_string);
122 }
123 }
124 }
125
126 // Gets the keys of a DictionaryValue.
127 std::vector<std::string> GetKeys(const DictionaryValue& dict) {
128 std::vector<std::string> keys;
129 for (DictionaryValue::key_iterator it = dict.begin_keys();
130 it != dict.end_keys(); ++it) {
131 keys.push_back(*it);
132 }
133 return keys;
134 }
135
136 // Creates quota heuristics for settings modification.
137 void GetModificationQuotaLimitHeuristics(QuotaLimitHeuristics* heuristics) {
138 QuotaLimitHeuristic::Config longLimitConfig = {
139 // See storage.json for current value.
140 api::storage::sync::MAX_WRITE_OPERATIONS_PER_HOUR,
141 base::TimeDelta::FromHours(1)
142 };
143 heuristics->push_back(
144 new ExtensionsQuotaService::TimedLimit(
145 longLimitConfig,
146 new QuotaLimitHeuristic::SingletonBucketMapper(),
147 "MAX_WRITE_OPERATIONS_PER_HOUR"));
148
149 // A max of 10 operations per minute, sustained over 10 minutes.
150 QuotaLimitHeuristic::Config shortLimitConfig = {
151 // See storage.json for current value.
152 api::storage::sync::MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE,
153 base::TimeDelta::FromMinutes(1)
154 };
155 heuristics->push_back(
156 new ExtensionsQuotaService::SustainedLimit(
157 base::TimeDelta::FromMinutes(10),
158 shortLimitConfig,
159 new QuotaLimitHeuristic::SingletonBucketMapper(),
160 "MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE"));
161 };
162
163 } // namespace
164
165 bool StorageGetFunction::RunWithStorage(ValueStore* storage) {
166 Value* input = NULL;
167 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));
168
169 switch (input->GetType()) {
170 case Value::TYPE_NULL:
171 return UseReadResult(storage->Get());
172
173 case Value::TYPE_STRING: {
174 std::string as_string;
175 input->GetAsString(&as_string);
176 return UseReadResult(storage->Get(as_string));
177 }
178
179 case Value::TYPE_LIST: {
180 std::vector<std::string> as_string_list;
181 AddAllStringValues(*static_cast<ListValue*>(input), &as_string_list);
182 return UseReadResult(storage->Get(as_string_list));
183 }
184
185 case Value::TYPE_DICTIONARY: {
186 DictionaryValue* as_dict = static_cast<DictionaryValue*>(input);
187 ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict));
188 if (result->HasError()) {
189 return UseReadResult(result.Pass());
190 }
191
192 DictionaryValue* with_default_values = as_dict->DeepCopy();
193 with_default_values->MergeDictionary(result->settings().get());
194 return UseReadResult(
195 ValueStore::MakeReadResult(with_default_values));
196 }
197
198 default:
199 return UseReadResult(
200 ValueStore::MakeReadResult(kUnsupportedArgumentType));
201 }
202 }
203
204 bool StorageGetBytesInUseFunction::RunWithStorage(ValueStore* storage) {
205 Value* input = NULL;
206 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));
207
208 size_t bytes_in_use = 0;
209
210 switch (input->GetType()) {
211 case Value::TYPE_NULL:
212 bytes_in_use = storage->GetBytesInUse();
213 break;
214
215 case Value::TYPE_STRING: {
216 std::string as_string;
217 input->GetAsString(&as_string);
218 bytes_in_use = storage->GetBytesInUse(as_string);
219 break;
220 }
221
222 case Value::TYPE_LIST: {
223 std::vector<std::string> as_string_list;
224 AddAllStringValues(*static_cast<ListValue*>(input), &as_string_list);
225 bytes_in_use = storage->GetBytesInUse(as_string_list);
226 break;
227 }
228
229 default:
230 error_ = kUnsupportedArgumentType;
231 return false;
232 }
233
234 SetResult(Value::CreateIntegerValue(bytes_in_use));
235 return true;
236 }
237
238 bool StorageSetFunction::RunWithStorage(ValueStore* storage) {
239 DictionaryValue* input = NULL;
240 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input));
241 return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input));
242 }
243
244 void StorageSetFunction::GetQuotaLimitHeuristics(
245 QuotaLimitHeuristics* heuristics) const {
246 GetModificationQuotaLimitHeuristics(heuristics);
247 }
248
249 bool StorageRemoveFunction::RunWithStorage(ValueStore* storage) {
250 Value* input = NULL;
251 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));
252
253 switch (input->GetType()) {
254 case Value::TYPE_STRING: {
255 std::string as_string;
256 input->GetAsString(&as_string);
257 return UseWriteResult(storage->Remove(as_string));
258 }
259
260 case Value::TYPE_LIST: {
261 std::vector<std::string> as_string_list;
262 AddAllStringValues(*static_cast<ListValue*>(input), &as_string_list);
263 return UseWriteResult(storage->Remove(as_string_list));
264 }
265
266 default:
267 return UseWriteResult(
268 ValueStore::MakeWriteResult(kUnsupportedArgumentType));
269 };
270 }
271
272 void StorageRemoveFunction::GetQuotaLimitHeuristics(
273 QuotaLimitHeuristics* heuristics) const {
274 GetModificationQuotaLimitHeuristics(heuristics);
275 }
276
277 bool StorageClearFunction::RunWithStorage(ValueStore* storage) {
278 return UseWriteResult(storage->Clear());
279 }
280
281 void StorageClearFunction::GetQuotaLimitHeuristics(
282 QuotaLimitHeuristics* heuristics) const {
283 GetModificationQuotaLimitHeuristics(heuristics);
284 }
285
286 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698