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/settings_storage_quota_enforcer.
h" | 5 #include "chrome/browser/extensions/api/storage/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/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/stl_util.h" | |
13 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
14 #include "chrome/browser/value_store/value_store_util.h" | 13 #include "chrome/browser/value_store/value_store_util.h" |
15 #include "extensions/common/extension_api.h" | 14 #include "extensions/common/extension_api.h" |
16 | 15 |
17 namespace util = value_store_util; | 16 namespace util = value_store_util; |
18 | 17 |
19 namespace extensions { | 18 namespace extensions { |
20 | 19 |
21 namespace { | 20 namespace { |
22 | 21 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 ValueStore::QUOTA_EXCEEDED, | 80 ValueStore::QUOTA_EXCEEDED, |
82 base::StringPrintf("%s quota exceeded", name), | 81 base::StringPrintf("%s quota exceeded", name), |
83 key.Pass())); | 82 key.Pass())); |
84 } | 83 } |
85 | 84 |
86 } // namespace | 85 } // namespace |
87 | 86 |
88 SettingsStorageQuotaEnforcer::SettingsStorageQuotaEnforcer( | 87 SettingsStorageQuotaEnforcer::SettingsStorageQuotaEnforcer( |
89 const Limits& limits, ValueStore* delegate) | 88 const Limits& limits, ValueStore* delegate) |
90 : limits_(limits), delegate_(delegate), used_total_(0) { | 89 : limits_(limits), delegate_(delegate), used_total_(0) { |
91 CalculateUsage(); | 90 ReadResult maybe_settings = delegate_->Get(); |
| 91 if (maybe_settings->HasError()) { |
| 92 LOG(WARNING) << "Failed to get initial settings for quota: " << |
| 93 maybe_settings->error().message; |
| 94 return; |
| 95 } |
| 96 |
| 97 for (base::DictionaryValue::Iterator it(maybe_settings->settings()); |
| 98 !it.IsAtEnd(); it.Advance()) { |
| 99 Allocate(it.key(), it.value(), &used_total_, &used_per_setting_); |
| 100 } |
92 } | 101 } |
93 | 102 |
94 SettingsStorageQuotaEnforcer::~SettingsStorageQuotaEnforcer() {} | 103 SettingsStorageQuotaEnforcer::~SettingsStorageQuotaEnforcer() {} |
95 | 104 |
96 size_t SettingsStorageQuotaEnforcer::GetBytesInUse(const std::string& key) { | 105 size_t SettingsStorageQuotaEnforcer::GetBytesInUse(const std::string& key) { |
97 std::map<std::string, size_t>::iterator maybe_used = | 106 std::map<std::string, size_t>::iterator maybe_used = |
98 used_per_setting_.find(key); | 107 used_per_setting_.find(key); |
99 return maybe_used == used_per_setting_.end() ? 0u : maybe_used->second; | 108 return maybe_used == used_per_setting_.end() ? 0u : maybe_used->second; |
100 } | 109 } |
101 | 110 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 } | 222 } |
214 return result.Pass(); | 223 return result.Pass(); |
215 } | 224 } |
216 | 225 |
217 ValueStore::WriteResult SettingsStorageQuotaEnforcer::Clear() { | 226 ValueStore::WriteResult SettingsStorageQuotaEnforcer::Clear() { |
218 WriteResult result = delegate_->Clear(); | 227 WriteResult result = delegate_->Clear(); |
219 if (result->HasError()) { | 228 if (result->HasError()) { |
220 return result.Pass(); | 229 return result.Pass(); |
221 } | 230 } |
222 | 231 |
223 used_per_setting_.clear(); | 232 while (!used_per_setting_.empty()) { |
224 used_total_ = 0; | 233 Free(&used_total_, &used_per_setting_, used_per_setting_.begin()->first); |
| 234 } |
225 return result.Pass(); | 235 return result.Pass(); |
226 } | 236 } |
227 | 237 |
228 bool SettingsStorageQuotaEnforcer::Restore() { | |
229 if (!delegate_->Restore()) { | |
230 // If we failed, we can't calculate the usage - that's okay, though, because | |
231 // next time we Restore() (if it succeeds) we will recalculate usage anyway. | |
232 // So reset storage counters now to free up resources. | |
233 used_per_setting_.clear(); | |
234 used_total_ = 0u; | |
235 return false; | |
236 } | |
237 CalculateUsage(); | |
238 return true; | |
239 } | |
240 | |
241 bool SettingsStorageQuotaEnforcer::RestoreKey(const std::string& key) { | |
242 if (!delegate_->RestoreKey(key)) | |
243 return false; | |
244 | |
245 ReadResult result = Get(key); | |
246 // If the key was deleted as a result of the Restore() call, free it. | |
247 if (!result->settings().HasKey(key) && ContainsKey(used_per_setting_, key)) | |
248 Free(&used_total_, &used_per_setting_, key); | |
249 return true; | |
250 } | |
251 | |
252 void SettingsStorageQuotaEnforcer::CalculateUsage() { | |
253 ReadResult maybe_settings = delegate_->Get(); | |
254 if (maybe_settings->HasError()) { | |
255 // Try to restore the database if it's corrupt. | |
256 if (maybe_settings->error().code == ValueStore::CORRUPTION && | |
257 delegate_->Restore()) { | |
258 maybe_settings = delegate_->Get(); | |
259 } else { | |
260 LOG(WARNING) << "Failed to get settings for quota:" | |
261 << maybe_settings->error().message; | |
262 return; | |
263 } | |
264 } | |
265 | |
266 for (base::DictionaryValue::Iterator it(maybe_settings->settings()); | |
267 !it.IsAtEnd(); | |
268 it.Advance()) { | |
269 Allocate(it.key(), it.value(), &used_total_, &used_per_setting_); | |
270 } | |
271 } | |
272 | |
273 } // namespace extensions | 238 } // namespace extensions |
OLD | NEW |