OLD | NEW |
---|---|
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" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 } | 66 } |
67 | 67 |
68 void SettingsFunction::AsyncRunWithStorage(ValueStore* storage) { | 68 void SettingsFunction::AsyncRunWithStorage(ValueStore* storage) { |
69 bool success = RunWithStorage(storage); | 69 bool success = RunWithStorage(storage); |
70 BrowserThread::PostTask( | 70 BrowserThread::PostTask( |
71 BrowserThread::UI, | 71 BrowserThread::UI, |
72 FROM_HERE, | 72 FROM_HERE, |
73 base::Bind(&SettingsFunction::SendResponse, this, success)); | 73 base::Bind(&SettingsFunction::SendResponse, this, success)); |
74 } | 74 } |
75 | 75 |
76 bool SettingsFunction::UseReadResult(ValueStore::ReadResult read_result) { | 76 bool SettingsFunction::UseReadResult(ValueStore::ReadResult result, |
77 if (read_result->HasError()) { | 77 ValueStore* storage) { |
78 error_ = read_result->error().message; | 78 if (result->HasError()) { |
79 if (result->error().code == ValueStore::CORRUPTION && | |
not at google - send to devlin
2014/02/14 19:35:56
result->IsCorruption()
Devlin
2014/02/18 23:55:22
Unneeded now.
| |
80 !tried_restoring_storage_) { | |
81 return RestoreStorageAndRetry(result->error(), storage); | |
82 } | |
83 error_ = result->error().message; | |
79 return false; | 84 return false; |
80 } | 85 } |
81 | 86 |
82 base::DictionaryValue* result = new base::DictionaryValue(); | 87 base::DictionaryValue* dict = new base::DictionaryValue(); |
not at google - send to devlin
2014/02/14 19:35:56
what was wrong with read_result vs result?
Devlin
2014/02/18 23:55:22
It was declared as |result| in the .h file (https:
| |
83 result->Swap(&read_result->settings()); | 88 dict->Swap(&result->settings()); |
84 SetResult(result); | 89 SetResult(dict); |
85 return true; | 90 return true; |
86 } | 91 } |
87 | 92 |
88 bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result) { | 93 bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result, |
94 ValueStore* storage) { | |
89 if (result->HasError()) { | 95 if (result->HasError()) { |
96 if (result->error().code == ValueStore::CORRUPTION && | |
not at google - send to devlin
2014/02/14 19:35:56
ditto
Devlin
2014/02/18 23:55:22
Unneeded now.
| |
97 !tried_restoring_storage_) { | |
98 return RestoreStorageAndRetry(result->error(), storage); | |
99 } | |
90 error_ = result->error().message; | 100 error_ = result->error().message; |
91 return false; | 101 return false; |
92 } | 102 } |
93 | 103 |
94 if (!result->changes().empty()) { | 104 if (!result->changes().empty()) { |
95 observers_->Notify( | 105 observers_->Notify( |
96 &SettingsObserver::OnSettingsChanged, | 106 &SettingsObserver::OnSettingsChanged, |
97 extension_id(), | 107 extension_id(), |
98 settings_namespace_, | 108 settings_namespace_, |
99 ValueStoreChange::ToJson(result->changes())); | 109 ValueStoreChange::ToJson(result->changes())); |
100 } | 110 } |
101 | 111 |
102 return true; | 112 return true; |
103 } | 113 } |
104 | 114 |
115 bool SettingsFunction::RestoreStorageAndRetry(const ValueStore::Error& error, | |
116 ValueStore* storage) { | |
117 DCHECK(!tried_restoring_storage_); | |
118 DCHECK(error.code == ValueStore::CORRUPTION); | |
119 tried_restoring_storage_ = true; | |
not at google - send to devlin
2014/02/14 19:35:56
I'd rather this state be entirely handled within t
Devlin
2014/02/18 23:55:22
Done (mostly - there's not really a need for a swi
| |
120 | |
121 // If the corruption is on a particular key, try to restore that key and | |
122 // re-run. | |
123 if (error.key.get()) { | |
124 if (storage->RestoreKey(*error.key)) | |
125 return RunWithStorage(storage); | |
126 } | |
127 | |
128 // If the full database is corrupted, try to restore the whole thing and | |
129 // re-run. | |
130 if (storage->Restore()) | |
131 return RunWithStorage(storage); | |
132 | |
133 // Failing that, there's nothing else we can do. | |
134 error_ = error.message; | |
135 return false; | |
136 } | |
137 | |
105 // Concrete settings functions | 138 // Concrete settings functions |
106 | 139 |
107 namespace { | 140 namespace { |
108 | 141 |
109 // Adds all StringValues from a ListValue to a vector of strings. | 142 // Adds all StringValues from a ListValue to a vector of strings. |
110 void AddAllStringValues(const base::ListValue& from, | 143 void AddAllStringValues(const base::ListValue& from, |
111 std::vector<std::string>* to) { | 144 std::vector<std::string>* to) { |
112 DCHECK(to->empty()); | 145 DCHECK(to->empty()); |
113 std::string as_string; | 146 std::string as_string; |
114 for (base::ListValue::const_iterator it = from.begin(); | 147 for (base::ListValue::const_iterator it = from.begin(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
154 }; | 187 }; |
155 | 188 |
156 } // namespace | 189 } // namespace |
157 | 190 |
158 bool StorageStorageAreaGetFunction::RunWithStorage(ValueStore* storage) { | 191 bool StorageStorageAreaGetFunction::RunWithStorage(ValueStore* storage) { |
159 base::Value* input = NULL; | 192 base::Value* input = NULL; |
160 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); | 193 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); |
161 | 194 |
162 switch (input->GetType()) { | 195 switch (input->GetType()) { |
163 case base::Value::TYPE_NULL: | 196 case base::Value::TYPE_NULL: |
164 return UseReadResult(storage->Get()); | 197 return UseReadResult(storage->Get(), storage); |
165 | 198 |
166 case base::Value::TYPE_STRING: { | 199 case base::Value::TYPE_STRING: { |
167 std::string as_string; | 200 std::string as_string; |
168 input->GetAsString(&as_string); | 201 input->GetAsString(&as_string); |
169 return UseReadResult(storage->Get(as_string)); | 202 return UseReadResult(storage->Get(as_string), storage); |
170 } | 203 } |
171 | 204 |
172 case base::Value::TYPE_LIST: { | 205 case base::Value::TYPE_LIST: { |
173 std::vector<std::string> as_string_list; | 206 std::vector<std::string> as_string_list; |
174 AddAllStringValues(*static_cast<base::ListValue*>(input), | 207 AddAllStringValues(*static_cast<base::ListValue*>(input), |
175 &as_string_list); | 208 &as_string_list); |
176 return UseReadResult(storage->Get(as_string_list)); | 209 return UseReadResult(storage->Get(as_string_list), storage); |
177 } | 210 } |
178 | 211 |
179 case base::Value::TYPE_DICTIONARY: { | 212 case base::Value::TYPE_DICTIONARY: { |
180 base::DictionaryValue* as_dict = static_cast<base::DictionaryValue*>(input ); | 213 base::DictionaryValue* as_dict = |
214 static_cast<base::DictionaryValue*>(input); | |
181 ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict)); | 215 ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict)); |
182 if (result->HasError()) { | 216 if (result->HasError()) { |
183 return UseReadResult(result.Pass()); | 217 return UseReadResult(result.Pass(), storage); |
184 } | 218 } |
185 | 219 |
186 base::DictionaryValue* with_default_values = as_dict->DeepCopy(); | 220 base::DictionaryValue* with_default_values = as_dict->DeepCopy(); |
187 with_default_values->MergeDictionary(&result->settings()); | 221 with_default_values->MergeDictionary(&result->settings()); |
188 return UseReadResult( | 222 return UseReadResult( |
189 ValueStore::MakeReadResult(make_scoped_ptr(with_default_values))); | 223 ValueStore::MakeReadResult(make_scoped_ptr(with_default_values)), |
224 storage); | |
190 } | 225 } |
191 | 226 |
192 default: | 227 default: |
193 EXTENSION_FUNCTION_VALIDATE(false); | 228 EXTENSION_FUNCTION_VALIDATE(false); |
194 return false; | 229 return false; |
195 } | 230 } |
196 } | 231 } |
197 | 232 |
198 bool StorageStorageAreaGetBytesInUseFunction::RunWithStorage( | 233 bool StorageStorageAreaGetBytesInUseFunction::RunWithStorage( |
199 ValueStore* storage) { | 234 ValueStore* storage) { |
(...skipping 27 matching lines...) Expand all Loading... | |
227 return false; | 262 return false; |
228 } | 263 } |
229 | 264 |
230 SetResult(new base::FundamentalValue(static_cast<int>(bytes_in_use))); | 265 SetResult(new base::FundamentalValue(static_cast<int>(bytes_in_use))); |
231 return true; | 266 return true; |
232 } | 267 } |
233 | 268 |
234 bool StorageStorageAreaSetFunction::RunWithStorage(ValueStore* storage) { | 269 bool StorageStorageAreaSetFunction::RunWithStorage(ValueStore* storage) { |
235 base::DictionaryValue* input = NULL; | 270 base::DictionaryValue* input = NULL; |
236 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input)); | 271 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input)); |
237 return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input)); | 272 return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input), storage); |
238 } | 273 } |
239 | 274 |
240 void StorageStorageAreaSetFunction::GetQuotaLimitHeuristics( | 275 void StorageStorageAreaSetFunction::GetQuotaLimitHeuristics( |
241 QuotaLimitHeuristics* heuristics) const { | 276 QuotaLimitHeuristics* heuristics) const { |
242 GetModificationQuotaLimitHeuristics(heuristics); | 277 GetModificationQuotaLimitHeuristics(heuristics); |
243 } | 278 } |
244 | 279 |
245 bool StorageStorageAreaRemoveFunction::RunWithStorage(ValueStore* storage) { | 280 bool StorageStorageAreaRemoveFunction::RunWithStorage(ValueStore* storage) { |
246 base::Value* input = NULL; | 281 base::Value* input = NULL; |
247 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); | 282 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); |
248 | 283 |
249 switch (input->GetType()) { | 284 switch (input->GetType()) { |
250 case base::Value::TYPE_STRING: { | 285 case base::Value::TYPE_STRING: { |
251 std::string as_string; | 286 std::string as_string; |
252 input->GetAsString(&as_string); | 287 input->GetAsString(&as_string); |
253 return UseWriteResult(storage->Remove(as_string)); | 288 return UseWriteResult(storage->Remove(as_string), storage); |
254 } | 289 } |
255 | 290 |
256 case base::Value::TYPE_LIST: { | 291 case base::Value::TYPE_LIST: { |
257 std::vector<std::string> as_string_list; | 292 std::vector<std::string> as_string_list; |
258 AddAllStringValues(*static_cast<base::ListValue*>(input), | 293 AddAllStringValues(*static_cast<base::ListValue*>(input), |
259 &as_string_list); | 294 &as_string_list); |
260 return UseWriteResult(storage->Remove(as_string_list)); | 295 return UseWriteResult(storage->Remove(as_string_list), storage); |
261 } | 296 } |
262 | 297 |
263 default: | 298 default: |
264 EXTENSION_FUNCTION_VALIDATE(false); | 299 EXTENSION_FUNCTION_VALIDATE(false); |
265 return false; | 300 return false; |
266 }; | 301 }; |
267 } | 302 } |
268 | 303 |
269 void StorageStorageAreaRemoveFunction::GetQuotaLimitHeuristics( | 304 void StorageStorageAreaRemoveFunction::GetQuotaLimitHeuristics( |
270 QuotaLimitHeuristics* heuristics) const { | 305 QuotaLimitHeuristics* heuristics) const { |
271 GetModificationQuotaLimitHeuristics(heuristics); | 306 GetModificationQuotaLimitHeuristics(heuristics); |
272 } | 307 } |
273 | 308 |
274 bool StorageStorageAreaClearFunction::RunWithStorage(ValueStore* storage) { | 309 bool StorageStorageAreaClearFunction::RunWithStorage(ValueStore* storage) { |
275 return UseWriteResult(storage->Clear()); | 310 return UseWriteResult(storage->Clear(), storage); |
276 } | 311 } |
277 | 312 |
278 void StorageStorageAreaClearFunction::GetQuotaLimitHeuristics( | 313 void StorageStorageAreaClearFunction::GetQuotaLimitHeuristics( |
279 QuotaLimitHeuristics* heuristics) const { | 314 QuotaLimitHeuristics* heuristics) const { |
280 GetModificationQuotaLimitHeuristics(heuristics); | 315 GetModificationQuotaLimitHeuristics(heuristics); |
281 } | 316 } |
282 | 317 |
283 } // namespace extensions | 318 } // namespace extensions |
OLD | NEW |