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

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

Issue 176963006: Resubmit: Add a Restore() method to ValueStore and make StorageAPI use it (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 10 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
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/api/storage/storage_api.h" 5 #include "chrome/browser/extensions/api/storage/storage_api.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/extensions/api/storage/settings_frontend.h" 13 #include "chrome/browser/extensions/api/storage/settings_frontend.h"
14 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/extensions/api/storage.h" 16 #include "chrome/common/extensions/api/storage.h"
17 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "extensions/browser/quota_service.h" 18 #include "extensions/browser/quota_service.h"
19 19
20 namespace extensions { 20 namespace extensions {
21 21
22 using content::BrowserThread; 22 using content::BrowserThread;
23 23
24 // SettingsFunction 24 // SettingsFunction
25 25
26 SettingsFunction::SettingsFunction() 26 SettingsFunction::SettingsFunction()
27 : settings_namespace_(settings_namespace::INVALID) {} 27 : settings_namespace_(settings_namespace::INVALID),
28 tried_restoring_storage_(false) {}
Devlin 2014/02/25 19:39:36 So, after more debugging than I'd like to admit, I
not at google - send to devlin 2014/02/25 20:39:20 Heh been there :)
28 29
29 SettingsFunction::~SettingsFunction() {} 30 SettingsFunction::~SettingsFunction() {}
30 31
31 bool SettingsFunction::ShouldSkipQuotaLimiting() const { 32 bool SettingsFunction::ShouldSkipQuotaLimiting() const {
32 // Only apply quota if this is for sync storage. 33 // Only apply quota if this is for sync storage.
33 std::string settings_namespace_string; 34 std::string settings_namespace_string;
34 if (!args_->GetString(0, &settings_namespace_string)) { 35 if (!args_->GetString(0, &settings_namespace_string)) {
35 // This should be EXTENSION_FUNCTION_VALIDATE(false) but there is no way 36 // This should be EXTENSION_FUNCTION_VALIDATE(false) but there is no way
36 // to signify that from this function. It will be caught in RunImpl(). 37 // to signify that from this function. It will be caught in RunImpl().
37 return false; 38 return false;
(...skipping 28 matching lines...) Expand all
66 } 67 }
67 68
68 void SettingsFunction::AsyncRunWithStorage(ValueStore* storage) { 69 void SettingsFunction::AsyncRunWithStorage(ValueStore* storage) {
69 bool success = RunWithStorage(storage); 70 bool success = RunWithStorage(storage);
70 BrowserThread::PostTask( 71 BrowserThread::PostTask(
71 BrowserThread::UI, 72 BrowserThread::UI,
72 FROM_HERE, 73 FROM_HERE,
73 base::Bind(&SettingsFunction::SendResponse, this, success)); 74 base::Bind(&SettingsFunction::SendResponse, this, success));
74 } 75 }
75 76
76 bool SettingsFunction::UseReadResult(ValueStore::ReadResult read_result) { 77 bool SettingsFunction::UseReadResult(ValueStore::ReadResult result,
77 if (read_result->HasError()) { 78 ValueStore* storage) {
78 error_ = read_result->error().message; 79 if (result->HasError())
79 return false; 80 return HandleError(result->error(), storage);
80 }
81 81
82 base::DictionaryValue* result = new base::DictionaryValue(); 82 base::DictionaryValue* dict = new base::DictionaryValue();
83 result->Swap(&read_result->settings()); 83 dict->Swap(&result->settings());
84 SetResult(result); 84 SetResult(dict);
85 return true; 85 return true;
86 } 86 }
87 87
88 bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result) { 88 bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result,
89 if (result->HasError()) { 89 ValueStore* storage) {
90 error_ = result->error().message; 90 if (result->HasError())
91 return false; 91 return HandleError(result->error(), storage);
92 }
93 92
94 if (!result->changes().empty()) { 93 if (!result->changes().empty()) {
95 observers_->Notify( 94 observers_->Notify(
96 &SettingsObserver::OnSettingsChanged, 95 &SettingsObserver::OnSettingsChanged,
97 extension_id(), 96 extension_id(),
98 settings_namespace_, 97 settings_namespace_,
99 ValueStoreChange::ToJson(result->changes())); 98 ValueStoreChange::ToJson(result->changes()));
100 } 99 }
101 100
102 return true; 101 return true;
103 } 102 }
104 103
104 bool SettingsFunction::HandleError(const ValueStore::Error& error,
105 ValueStore* storage) {
106 // If the method failed due to corruption, and we haven't tried to fix it, we
107 // can try to restore the storage and re-run it. Otherwise, the method has
108 // failed.
109 if (error.code == ValueStore::CORRUPTION && !tried_restoring_storage_) {
110 tried_restoring_storage_ = true;
111
112 // If the corruption is on a particular key, try to restore that key and
113 // re-run.
114 if (error.key.get() && storage->RestoreKey(*error.key))
115 return RunWithStorage(storage);
116
117 // If the full database is corrupted, try to restore the whole thing and
118 // re-run.
119 if (storage->Restore())
120 return RunWithStorage(storage);
121 }
122
123 error_ = error.message;
124 return false;
125 }
126
105 // Concrete settings functions 127 // Concrete settings functions
106 128
107 namespace { 129 namespace {
108 130
109 // Adds all StringValues from a ListValue to a vector of strings. 131 // Adds all StringValues from a ListValue to a vector of strings.
110 void AddAllStringValues(const base::ListValue& from, 132 void AddAllStringValues(const base::ListValue& from,
111 std::vector<std::string>* to) { 133 std::vector<std::string>* to) {
112 DCHECK(to->empty()); 134 DCHECK(to->empty());
113 std::string as_string; 135 std::string as_string;
114 for (base::ListValue::const_iterator it = from.begin(); 136 for (base::ListValue::const_iterator it = from.begin();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 }; 176 };
155 177
156 } // namespace 178 } // namespace
157 179
158 bool StorageStorageAreaGetFunction::RunWithStorage(ValueStore* storage) { 180 bool StorageStorageAreaGetFunction::RunWithStorage(ValueStore* storage) {
159 base::Value* input = NULL; 181 base::Value* input = NULL;
160 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); 182 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));
161 183
162 switch (input->GetType()) { 184 switch (input->GetType()) {
163 case base::Value::TYPE_NULL: 185 case base::Value::TYPE_NULL:
164 return UseReadResult(storage->Get()); 186 return UseReadResult(storage->Get(), storage);
165 187
166 case base::Value::TYPE_STRING: { 188 case base::Value::TYPE_STRING: {
167 std::string as_string; 189 std::string as_string;
168 input->GetAsString(&as_string); 190 input->GetAsString(&as_string);
169 return UseReadResult(storage->Get(as_string)); 191 return UseReadResult(storage->Get(as_string), storage);
170 } 192 }
171 193
172 case base::Value::TYPE_LIST: { 194 case base::Value::TYPE_LIST: {
173 std::vector<std::string> as_string_list; 195 std::vector<std::string> as_string_list;
174 AddAllStringValues(*static_cast<base::ListValue*>(input), 196 AddAllStringValues(*static_cast<base::ListValue*>(input),
175 &as_string_list); 197 &as_string_list);
176 return UseReadResult(storage->Get(as_string_list)); 198 return UseReadResult(storage->Get(as_string_list), storage);
177 } 199 }
178 200
179 case base::Value::TYPE_DICTIONARY: { 201 case base::Value::TYPE_DICTIONARY: {
180 base::DictionaryValue* as_dict = static_cast<base::DictionaryValue*>(input ); 202 base::DictionaryValue* as_dict =
203 static_cast<base::DictionaryValue*>(input);
181 ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict)); 204 ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict));
182 if (result->HasError()) { 205 if (result->HasError()) {
183 return UseReadResult(result.Pass()); 206 return UseReadResult(result.Pass(), storage);
184 } 207 }
185 208
186 base::DictionaryValue* with_default_values = as_dict->DeepCopy(); 209 base::DictionaryValue* with_default_values = as_dict->DeepCopy();
187 with_default_values->MergeDictionary(&result->settings()); 210 with_default_values->MergeDictionary(&result->settings());
188 return UseReadResult( 211 return UseReadResult(
189 ValueStore::MakeReadResult(make_scoped_ptr(with_default_values))); 212 ValueStore::MakeReadResult(make_scoped_ptr(with_default_values)),
213 storage);
190 } 214 }
191 215
192 default: 216 default:
193 EXTENSION_FUNCTION_VALIDATE(false); 217 EXTENSION_FUNCTION_VALIDATE(false);
194 return false; 218 return false;
195 } 219 }
196 } 220 }
197 221
198 bool StorageStorageAreaGetBytesInUseFunction::RunWithStorage( 222 bool StorageStorageAreaGetBytesInUseFunction::RunWithStorage(
199 ValueStore* storage) { 223 ValueStore* storage) {
(...skipping 27 matching lines...) Expand all
227 return false; 251 return false;
228 } 252 }
229 253
230 SetResult(new base::FundamentalValue(static_cast<int>(bytes_in_use))); 254 SetResult(new base::FundamentalValue(static_cast<int>(bytes_in_use)));
231 return true; 255 return true;
232 } 256 }
233 257
234 bool StorageStorageAreaSetFunction::RunWithStorage(ValueStore* storage) { 258 bool StorageStorageAreaSetFunction::RunWithStorage(ValueStore* storage) {
235 base::DictionaryValue* input = NULL; 259 base::DictionaryValue* input = NULL;
236 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input)); 260 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input));
237 return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input)); 261 return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input), storage);
238 } 262 }
239 263
240 void StorageStorageAreaSetFunction::GetQuotaLimitHeuristics( 264 void StorageStorageAreaSetFunction::GetQuotaLimitHeuristics(
241 QuotaLimitHeuristics* heuristics) const { 265 QuotaLimitHeuristics* heuristics) const {
242 GetModificationQuotaLimitHeuristics(heuristics); 266 GetModificationQuotaLimitHeuristics(heuristics);
243 } 267 }
244 268
245 bool StorageStorageAreaRemoveFunction::RunWithStorage(ValueStore* storage) { 269 bool StorageStorageAreaRemoveFunction::RunWithStorage(ValueStore* storage) {
246 base::Value* input = NULL; 270 base::Value* input = NULL;
247 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); 271 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input));
248 272
249 switch (input->GetType()) { 273 switch (input->GetType()) {
250 case base::Value::TYPE_STRING: { 274 case base::Value::TYPE_STRING: {
251 std::string as_string; 275 std::string as_string;
252 input->GetAsString(&as_string); 276 input->GetAsString(&as_string);
253 return UseWriteResult(storage->Remove(as_string)); 277 return UseWriteResult(storage->Remove(as_string), storage);
254 } 278 }
255 279
256 case base::Value::TYPE_LIST: { 280 case base::Value::TYPE_LIST: {
257 std::vector<std::string> as_string_list; 281 std::vector<std::string> as_string_list;
258 AddAllStringValues(*static_cast<base::ListValue*>(input), 282 AddAllStringValues(*static_cast<base::ListValue*>(input),
259 &as_string_list); 283 &as_string_list);
260 return UseWriteResult(storage->Remove(as_string_list)); 284 return UseWriteResult(storage->Remove(as_string_list), storage);
261 } 285 }
262 286
263 default: 287 default:
264 EXTENSION_FUNCTION_VALIDATE(false); 288 EXTENSION_FUNCTION_VALIDATE(false);
265 return false; 289 return false;
266 }; 290 };
267 } 291 }
268 292
269 void StorageStorageAreaRemoveFunction::GetQuotaLimitHeuristics( 293 void StorageStorageAreaRemoveFunction::GetQuotaLimitHeuristics(
270 QuotaLimitHeuristics* heuristics) const { 294 QuotaLimitHeuristics* heuristics) const {
271 GetModificationQuotaLimitHeuristics(heuristics); 295 GetModificationQuotaLimitHeuristics(heuristics);
272 } 296 }
273 297
274 bool StorageStorageAreaClearFunction::RunWithStorage(ValueStore* storage) { 298 bool StorageStorageAreaClearFunction::RunWithStorage(ValueStore* storage) {
275 return UseWriteResult(storage->Clear()); 299 return UseWriteResult(storage->Clear(), storage);
276 } 300 }
277 301
278 void StorageStorageAreaClearFunction::GetQuotaLimitHeuristics( 302 void StorageStorageAreaClearFunction::GetQuotaLimitHeuristics(
279 QuotaLimitHeuristics* heuristics) const { 303 QuotaLimitHeuristics* heuristics) const {
280 GetModificationQuotaLimitHeuristics(heuristics); 304 GetModificationQuotaLimitHeuristics(heuristics);
281 } 305 }
282 306
283 } // namespace extensions 307 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/storage/storage_api.h ('k') | chrome/browser/extensions/api/storage/storage_api_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698