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 result, | 76 bool SettingsFunction::UseReadResult(ValueStore::ReadResult read_result) { |
77 ValueStore* storage) { | 77 if (read_result->HasError()) { |
78 if (result->HasError()) | 78 error_ = read_result->error().message; |
79 return HandleError(result->error(), storage); | 79 return false; |
| 80 } |
80 | 81 |
81 base::DictionaryValue* dict = new base::DictionaryValue(); | 82 base::DictionaryValue* result = new base::DictionaryValue(); |
82 dict->Swap(&result->settings()); | 83 result->Swap(&read_result->settings()); |
83 SetResult(dict); | 84 SetResult(result); |
84 return true; | 85 return true; |
85 } | 86 } |
86 | 87 |
87 bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result, | 88 bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result) { |
88 ValueStore* storage) { | 89 if (result->HasError()) { |
89 if (result->HasError()) | 90 error_ = result->error().message; |
90 return HandleError(result->error(), storage); | 91 return false; |
| 92 } |
91 | 93 |
92 if (!result->changes().empty()) { | 94 if (!result->changes().empty()) { |
93 observers_->Notify( | 95 observers_->Notify( |
94 &SettingsObserver::OnSettingsChanged, | 96 &SettingsObserver::OnSettingsChanged, |
95 extension_id(), | 97 extension_id(), |
96 settings_namespace_, | 98 settings_namespace_, |
97 ValueStoreChange::ToJson(result->changes())); | 99 ValueStoreChange::ToJson(result->changes())); |
98 } | 100 } |
99 | 101 |
100 return true; | 102 return true; |
101 } | 103 } |
102 | 104 |
103 bool SettingsFunction::HandleError(const ValueStore::Error& error, | |
104 ValueStore* storage) { | |
105 // If the method failed due to corruption, and we haven't tried to fix it, we | |
106 // can try to restore the storage and re-run it. Otherwise, the method has | |
107 // failed. | |
108 if (error.code == ValueStore::CORRUPTION && !tried_restoring_storage_) { | |
109 tried_restoring_storage_ = true; | |
110 | |
111 // If the corruption is on a particular key, try to restore that key and | |
112 // re-run. | |
113 if (error.key.get() && storage->RestoreKey(*error.key)) | |
114 return RunWithStorage(storage); | |
115 | |
116 // If the full database is corrupted, try to restore the whole thing and | |
117 // re-run. | |
118 if (storage->Restore()) | |
119 return RunWithStorage(storage); | |
120 } | |
121 | |
122 error_ = error.message; | |
123 return false; | |
124 } | |
125 | |
126 // Concrete settings functions | 105 // Concrete settings functions |
127 | 106 |
128 namespace { | 107 namespace { |
129 | 108 |
130 // Adds all StringValues from a ListValue to a vector of strings. | 109 // Adds all StringValues from a ListValue to a vector of strings. |
131 void AddAllStringValues(const base::ListValue& from, | 110 void AddAllStringValues(const base::ListValue& from, |
132 std::vector<std::string>* to) { | 111 std::vector<std::string>* to) { |
133 DCHECK(to->empty()); | 112 DCHECK(to->empty()); |
134 std::string as_string; | 113 std::string as_string; |
135 for (base::ListValue::const_iterator it = from.begin(); | 114 for (base::ListValue::const_iterator it = from.begin(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 }; | 154 }; |
176 | 155 |
177 } // namespace | 156 } // namespace |
178 | 157 |
179 bool StorageStorageAreaGetFunction::RunWithStorage(ValueStore* storage) { | 158 bool StorageStorageAreaGetFunction::RunWithStorage(ValueStore* storage) { |
180 base::Value* input = NULL; | 159 base::Value* input = NULL; |
181 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); | 160 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); |
182 | 161 |
183 switch (input->GetType()) { | 162 switch (input->GetType()) { |
184 case base::Value::TYPE_NULL: | 163 case base::Value::TYPE_NULL: |
185 return UseReadResult(storage->Get(), storage); | 164 return UseReadResult(storage->Get()); |
186 | 165 |
187 case base::Value::TYPE_STRING: { | 166 case base::Value::TYPE_STRING: { |
188 std::string as_string; | 167 std::string as_string; |
189 input->GetAsString(&as_string); | 168 input->GetAsString(&as_string); |
190 return UseReadResult(storage->Get(as_string), storage); | 169 return UseReadResult(storage->Get(as_string)); |
191 } | 170 } |
192 | 171 |
193 case base::Value::TYPE_LIST: { | 172 case base::Value::TYPE_LIST: { |
194 std::vector<std::string> as_string_list; | 173 std::vector<std::string> as_string_list; |
195 AddAllStringValues(*static_cast<base::ListValue*>(input), | 174 AddAllStringValues(*static_cast<base::ListValue*>(input), |
196 &as_string_list); | 175 &as_string_list); |
197 return UseReadResult(storage->Get(as_string_list), storage); | 176 return UseReadResult(storage->Get(as_string_list)); |
198 } | 177 } |
199 | 178 |
200 case base::Value::TYPE_DICTIONARY: { | 179 case base::Value::TYPE_DICTIONARY: { |
201 base::DictionaryValue* as_dict = | 180 base::DictionaryValue* as_dict = static_cast<base::DictionaryValue*>(input
); |
202 static_cast<base::DictionaryValue*>(input); | |
203 ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict)); | 181 ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict)); |
204 if (result->HasError()) { | 182 if (result->HasError()) { |
205 return UseReadResult(result.Pass(), storage); | 183 return UseReadResult(result.Pass()); |
206 } | 184 } |
207 | 185 |
208 base::DictionaryValue* with_default_values = as_dict->DeepCopy(); | 186 base::DictionaryValue* with_default_values = as_dict->DeepCopy(); |
209 with_default_values->MergeDictionary(&result->settings()); | 187 with_default_values->MergeDictionary(&result->settings()); |
210 return UseReadResult( | 188 return UseReadResult( |
211 ValueStore::MakeReadResult(make_scoped_ptr(with_default_values)), | 189 ValueStore::MakeReadResult(make_scoped_ptr(with_default_values))); |
212 storage); | |
213 } | 190 } |
214 | 191 |
215 default: | 192 default: |
216 EXTENSION_FUNCTION_VALIDATE(false); | 193 EXTENSION_FUNCTION_VALIDATE(false); |
217 return false; | 194 return false; |
218 } | 195 } |
219 } | 196 } |
220 | 197 |
221 bool StorageStorageAreaGetBytesInUseFunction::RunWithStorage( | 198 bool StorageStorageAreaGetBytesInUseFunction::RunWithStorage( |
222 ValueStore* storage) { | 199 ValueStore* storage) { |
(...skipping 27 matching lines...) Expand all Loading... |
250 return false; | 227 return false; |
251 } | 228 } |
252 | 229 |
253 SetResult(new base::FundamentalValue(static_cast<int>(bytes_in_use))); | 230 SetResult(new base::FundamentalValue(static_cast<int>(bytes_in_use))); |
254 return true; | 231 return true; |
255 } | 232 } |
256 | 233 |
257 bool StorageStorageAreaSetFunction::RunWithStorage(ValueStore* storage) { | 234 bool StorageStorageAreaSetFunction::RunWithStorage(ValueStore* storage) { |
258 base::DictionaryValue* input = NULL; | 235 base::DictionaryValue* input = NULL; |
259 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input)); | 236 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input)); |
260 return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input), storage); | 237 return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input)); |
261 } | 238 } |
262 | 239 |
263 void StorageStorageAreaSetFunction::GetQuotaLimitHeuristics( | 240 void StorageStorageAreaSetFunction::GetQuotaLimitHeuristics( |
264 QuotaLimitHeuristics* heuristics) const { | 241 QuotaLimitHeuristics* heuristics) const { |
265 GetModificationQuotaLimitHeuristics(heuristics); | 242 GetModificationQuotaLimitHeuristics(heuristics); |
266 } | 243 } |
267 | 244 |
268 bool StorageStorageAreaRemoveFunction::RunWithStorage(ValueStore* storage) { | 245 bool StorageStorageAreaRemoveFunction::RunWithStorage(ValueStore* storage) { |
269 base::Value* input = NULL; | 246 base::Value* input = NULL; |
270 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); | 247 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &input)); |
271 | 248 |
272 switch (input->GetType()) { | 249 switch (input->GetType()) { |
273 case base::Value::TYPE_STRING: { | 250 case base::Value::TYPE_STRING: { |
274 std::string as_string; | 251 std::string as_string; |
275 input->GetAsString(&as_string); | 252 input->GetAsString(&as_string); |
276 return UseWriteResult(storage->Remove(as_string), storage); | 253 return UseWriteResult(storage->Remove(as_string)); |
277 } | 254 } |
278 | 255 |
279 case base::Value::TYPE_LIST: { | 256 case base::Value::TYPE_LIST: { |
280 std::vector<std::string> as_string_list; | 257 std::vector<std::string> as_string_list; |
281 AddAllStringValues(*static_cast<base::ListValue*>(input), | 258 AddAllStringValues(*static_cast<base::ListValue*>(input), |
282 &as_string_list); | 259 &as_string_list); |
283 return UseWriteResult(storage->Remove(as_string_list), storage); | 260 return UseWriteResult(storage->Remove(as_string_list)); |
284 } | 261 } |
285 | 262 |
286 default: | 263 default: |
287 EXTENSION_FUNCTION_VALIDATE(false); | 264 EXTENSION_FUNCTION_VALIDATE(false); |
288 return false; | 265 return false; |
289 }; | 266 }; |
290 } | 267 } |
291 | 268 |
292 void StorageStorageAreaRemoveFunction::GetQuotaLimitHeuristics( | 269 void StorageStorageAreaRemoveFunction::GetQuotaLimitHeuristics( |
293 QuotaLimitHeuristics* heuristics) const { | 270 QuotaLimitHeuristics* heuristics) const { |
294 GetModificationQuotaLimitHeuristics(heuristics); | 271 GetModificationQuotaLimitHeuristics(heuristics); |
295 } | 272 } |
296 | 273 |
297 bool StorageStorageAreaClearFunction::RunWithStorage(ValueStore* storage) { | 274 bool StorageStorageAreaClearFunction::RunWithStorage(ValueStore* storage) { |
298 return UseWriteResult(storage->Clear(), storage); | 275 return UseWriteResult(storage->Clear()); |
299 } | 276 } |
300 | 277 |
301 void StorageStorageAreaClearFunction::GetQuotaLimitHeuristics( | 278 void StorageStorageAreaClearFunction::GetQuotaLimitHeuristics( |
302 QuotaLimitHeuristics* heuristics) const { | 279 QuotaLimitHeuristics* heuristics) const { |
303 GetModificationQuotaLimitHeuristics(heuristics); | 280 GetModificationQuotaLimitHeuristics(heuristics); |
304 } | 281 } |
305 | 282 |
306 } // namespace extensions | 283 } // namespace extensions |
OLD | NEW |