OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "webkit/browser/quota/storage_monitor.h" | 5 #include "storage/browser/quota/storage_monitor.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "net/base/net_util.h" | 10 #include "net/base/net_util.h" |
11 #include "webkit/browser/quota/quota_manager.h" | 11 #include "storage/browser/quota/quota_manager.h" |
12 #include "webkit/common/quota/quota_status_code.h" | 12 #include "storage/common/quota/quota_status_code.h" |
13 | 13 |
14 namespace quota { | 14 namespace quota { |
15 | 15 |
16 // StorageObserverList: | 16 // StorageObserverList: |
17 | 17 |
18 StorageObserverList::ObserverState::ObserverState() | 18 StorageObserverList::ObserverState::ObserverState() : requires_update(false) { |
19 : requires_update(false) { | |
20 } | 19 } |
21 | 20 |
22 StorageObserverList::StorageObserverList() {} | 21 StorageObserverList::StorageObserverList() { |
| 22 } |
23 | 23 |
24 StorageObserverList::~StorageObserverList() {} | 24 StorageObserverList::~StorageObserverList() { |
| 25 } |
25 | 26 |
26 void StorageObserverList::AddObserver( | 27 void StorageObserverList::AddObserver( |
27 StorageObserver* observer, const StorageObserver::MonitorParams& params) { | 28 StorageObserver* observer, |
| 29 const StorageObserver::MonitorParams& params) { |
28 ObserverState& observer_state = observers_[observer]; | 30 ObserverState& observer_state = observers_[observer]; |
29 observer_state.origin = params.filter.origin; | 31 observer_state.origin = params.filter.origin; |
30 observer_state.rate = params.rate; | 32 observer_state.rate = params.rate; |
31 } | 33 } |
32 | 34 |
33 void StorageObserverList::RemoveObserver(StorageObserver* observer) { | 35 void StorageObserverList::RemoveObserver(StorageObserver* observer) { |
34 observers_.erase(observer); | 36 observers_.erase(observer); |
35 } | 37 } |
36 | 38 |
37 int StorageObserverList::ObserverCount() const { | 39 int StorageObserverList::ObserverCount() const { |
38 return observers_.size(); | 40 return observers_.size(); |
39 } | 41 } |
40 | 42 |
41 void StorageObserverList::OnStorageChange(const StorageObserver::Event& event) { | 43 void StorageObserverList::OnStorageChange(const StorageObserver::Event& event) { |
42 for (StorageObserverStateMap::iterator it = observers_.begin(); | 44 for (StorageObserverStateMap::iterator it = observers_.begin(); |
43 it != observers_.end(); ++it) { | 45 it != observers_.end(); |
| 46 ++it) { |
44 it->second.requires_update = true; | 47 it->second.requires_update = true; |
45 } | 48 } |
46 | 49 |
47 MaybeDispatchEvent(event); | 50 MaybeDispatchEvent(event); |
48 } | 51 } |
49 | 52 |
50 void StorageObserverList::MaybeDispatchEvent( | 53 void StorageObserverList::MaybeDispatchEvent( |
51 const StorageObserver::Event& event) { | 54 const StorageObserver::Event& event) { |
52 notification_timer_.Stop(); | 55 notification_timer_.Stop(); |
53 base::TimeDelta min_delay = base::TimeDelta::Max(); | 56 base::TimeDelta min_delay = base::TimeDelta::Max(); |
54 bool all_observers_notified = true; | 57 bool all_observers_notified = true; |
55 | 58 |
56 for (StorageObserverStateMap::iterator it = observers_.begin(); | 59 for (StorageObserverStateMap::iterator it = observers_.begin(); |
57 it != observers_.end(); ++it) { | 60 it != observers_.end(); |
| 61 ++it) { |
58 if (!it->second.requires_update) | 62 if (!it->second.requires_update) |
59 continue; | 63 continue; |
60 | 64 |
61 base::TimeTicks current_time = base::TimeTicks::Now(); | 65 base::TimeTicks current_time = base::TimeTicks::Now(); |
62 base::TimeDelta delta = current_time - it->second.last_notification_time; | 66 base::TimeDelta delta = current_time - it->second.last_notification_time; |
63 if (it->second.last_notification_time.is_null() || | 67 if (it->second.last_notification_time.is_null() || |
64 delta >= it->second.rate) { | 68 delta >= it->second.rate) { |
65 it->second.requires_update = false; | 69 it->second.requires_update = false; |
66 it->second.last_notification_time = current_time; | 70 it->second.last_notification_time = current_time; |
67 | 71 |
(...skipping 17 matching lines...) Expand all Loading... |
85 } | 89 } |
86 } | 90 } |
87 | 91 |
88 // We need to respect the notification rate specified by observers. So if it | 92 // We need to respect the notification rate specified by observers. So if it |
89 // is too soon to dispatch an event to an observer, save the event and | 93 // is too soon to dispatch an event to an observer, save the event and |
90 // dispatch it after a delay. If we simply drop the event, another one may | 94 // dispatch it after a delay. If we simply drop the event, another one may |
91 // not arrive anytime soon and the observer will miss the most recent event. | 95 // not arrive anytime soon and the observer will miss the most recent event. |
92 if (!all_observers_notified) { | 96 if (!all_observers_notified) { |
93 pending_event_ = event; | 97 pending_event_ = event; |
94 notification_timer_.Start( | 98 notification_timer_.Start( |
95 FROM_HERE, | 99 FROM_HERE, min_delay, this, &StorageObserverList::DispatchPendingEvent); |
96 min_delay, | |
97 this, | |
98 &StorageObserverList::DispatchPendingEvent); | |
99 } | 100 } |
100 } | 101 } |
101 | 102 |
102 void StorageObserverList::ScheduleUpdateForObserver(StorageObserver* observer) { | 103 void StorageObserverList::ScheduleUpdateForObserver(StorageObserver* observer) { |
103 DCHECK(ContainsKey(observers_, observer)); | 104 DCHECK(ContainsKey(observers_, observer)); |
104 observers_[observer].requires_update = true; | 105 observers_[observer].requires_update = true; |
105 } | 106 } |
106 | 107 |
107 void StorageObserverList::DispatchPendingEvent() { | 108 void StorageObserverList::DispatchPendingEvent() { |
108 MaybeDispatchEvent(pending_event_); | 109 MaybeDispatchEvent(pending_event_); |
109 } | 110 } |
110 | 111 |
111 | |
112 // HostStorageObservers: | 112 // HostStorageObservers: |
113 | 113 |
114 HostStorageObservers::HostStorageObservers(QuotaManager* quota_manager) | 114 HostStorageObservers::HostStorageObservers(QuotaManager* quota_manager) |
115 : quota_manager_(quota_manager), | 115 : quota_manager_(quota_manager), |
116 initialized_(false), | 116 initialized_(false), |
117 initializing_(false), | 117 initializing_(false), |
118 event_occurred_before_init_(false), | 118 event_occurred_before_init_(false), |
119 usage_deltas_during_init_(0), | 119 usage_deltas_during_init_(0), |
120 cached_usage_(0), | 120 cached_usage_(0), |
121 cached_quota_(0), | 121 cached_quota_(0), |
122 weak_factory_(this) { | 122 weak_factory_(this) { |
123 } | 123 } |
124 | 124 |
125 HostStorageObservers::~HostStorageObservers() {} | 125 HostStorageObservers::~HostStorageObservers() { |
| 126 } |
126 | 127 |
127 void HostStorageObservers::AddObserver( | 128 void HostStorageObservers::AddObserver( |
128 StorageObserver* observer, | 129 StorageObserver* observer, |
129 const StorageObserver::MonitorParams& params) { | 130 const StorageObserver::MonitorParams& params) { |
130 observers_.AddObserver(observer, params); | 131 observers_.AddObserver(observer, params); |
131 | 132 |
132 if (!params.dispatch_initial_state) | 133 if (!params.dispatch_initial_state) |
133 return; | 134 return; |
134 | 135 |
135 if (initialized_) { | 136 if (initialized_) { |
(...skipping 12 matching lines...) Expand all Loading... |
148 | 149 |
149 void HostStorageObservers::RemoveObserver(StorageObserver* observer) { | 150 void HostStorageObservers::RemoveObserver(StorageObserver* observer) { |
150 observers_.RemoveObserver(observer); | 151 observers_.RemoveObserver(observer); |
151 } | 152 } |
152 | 153 |
153 bool HostStorageObservers::ContainsObservers() const { | 154 bool HostStorageObservers::ContainsObservers() const { |
154 return observers_.ObserverCount() > 0; | 155 return observers_.ObserverCount() > 0; |
155 } | 156 } |
156 | 157 |
157 void HostStorageObservers::NotifyUsageChange( | 158 void HostStorageObservers::NotifyUsageChange( |
158 const StorageObserver::Filter& filter, int64 delta) { | 159 const StorageObserver::Filter& filter, |
| 160 int64 delta) { |
159 if (initialized_) { | 161 if (initialized_) { |
160 cached_usage_ += delta; | 162 cached_usage_ += delta; |
161 DispatchEvent(filter, true); | 163 DispatchEvent(filter, true); |
162 return; | 164 return; |
163 } | 165 } |
164 | 166 |
165 // If a storage change occurs before initialization, ensure all observers will | 167 // If a storage change occurs before initialization, ensure all observers will |
166 // receive an event once initialization is complete. | 168 // receive an event once initialization is complete. |
167 event_occurred_before_init_ = true; | 169 event_occurred_before_init_ = true; |
168 | 170 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 initializing_ = false; | 203 initializing_ = false; |
202 if (status != kQuotaStatusOk) | 204 if (status != kQuotaStatusOk) |
203 return; | 205 return; |
204 | 206 |
205 initialized_ = true; | 207 initialized_ = true; |
206 cached_quota_ = quota; | 208 cached_quota_ = quota; |
207 cached_usage_ = usage + usage_deltas_during_init_; | 209 cached_usage_ = usage + usage_deltas_during_init_; |
208 DispatchEvent(filter, event_occurred_before_init_); | 210 DispatchEvent(filter, event_occurred_before_init_); |
209 } | 211 } |
210 | 212 |
211 void HostStorageObservers::DispatchEvent( | 213 void HostStorageObservers::DispatchEvent(const StorageObserver::Filter& filter, |
212 const StorageObserver::Filter& filter, bool is_update) { | 214 bool is_update) { |
213 StorageObserver::Event event(filter, | 215 StorageObserver::Event event(filter, |
214 std::max<int64>(cached_usage_, 0), | 216 std::max<int64>(cached_usage_, 0), |
215 std::max<int64>(cached_quota_, 0)); | 217 std::max<int64>(cached_quota_, 0)); |
216 if (is_update) | 218 if (is_update) |
217 observers_.OnStorageChange(event); | 219 observers_.OnStorageChange(event); |
218 else | 220 else |
219 observers_.MaybeDispatchEvent(event); | 221 observers_.MaybeDispatchEvent(event); |
220 } | 222 } |
221 | 223 |
222 | |
223 // StorageTypeObservers: | 224 // StorageTypeObservers: |
224 | 225 |
225 StorageTypeObservers::StorageTypeObservers(QuotaManager* quota_manager) | 226 StorageTypeObservers::StorageTypeObservers(QuotaManager* quota_manager) |
226 : quota_manager_(quota_manager) { | 227 : quota_manager_(quota_manager) { |
227 } | 228 } |
228 | 229 |
229 StorageTypeObservers::~StorageTypeObservers() { | 230 StorageTypeObservers::~StorageTypeObservers() { |
230 STLDeleteValues(&host_observers_map_); | 231 STLDeleteValues(&host_observers_map_); |
231 } | 232 } |
232 | 233 |
233 void StorageTypeObservers::AddObserver( | 234 void StorageTypeObservers::AddObserver( |
234 StorageObserver* observer, const StorageObserver::MonitorParams& params) { | 235 StorageObserver* observer, |
| 236 const StorageObserver::MonitorParams& params) { |
235 std::string host = net::GetHostOrSpecFromURL(params.filter.origin); | 237 std::string host = net::GetHostOrSpecFromURL(params.filter.origin); |
236 if (host.empty()) | 238 if (host.empty()) |
237 return; | 239 return; |
238 | 240 |
239 HostStorageObservers* host_observers = NULL; | 241 HostStorageObservers* host_observers = NULL; |
240 HostObserversMap::iterator it = host_observers_map_.find(host); | 242 HostObserversMap::iterator it = host_observers_map_.find(host); |
241 if (it == host_observers_map_.end()) { | 243 if (it == host_observers_map_.end()) { |
242 host_observers = new HostStorageObservers(quota_manager_); | 244 host_observers = new HostStorageObservers(quota_manager_); |
243 host_observers_map_[host] = host_observers; | 245 host_observers_map_[host] = host_observers; |
244 } else { | 246 } else { |
245 host_observers = it->second; | 247 host_observers = it->second; |
246 } | 248 } |
247 | 249 |
248 host_observers->AddObserver(observer, params); | 250 host_observers->AddObserver(observer, params); |
249 } | 251 } |
250 | 252 |
251 void StorageTypeObservers::RemoveObserver(StorageObserver* observer) { | 253 void StorageTypeObservers::RemoveObserver(StorageObserver* observer) { |
252 for (HostObserversMap::iterator it = host_observers_map_.begin(); | 254 for (HostObserversMap::iterator it = host_observers_map_.begin(); |
253 it != host_observers_map_.end(); ) { | 255 it != host_observers_map_.end();) { |
254 it->second->RemoveObserver(observer); | 256 it->second->RemoveObserver(observer); |
255 if (!it->second->ContainsObservers()) { | 257 if (!it->second->ContainsObservers()) { |
256 delete it->second; | 258 delete it->second; |
257 host_observers_map_.erase(it++); | 259 host_observers_map_.erase(it++); |
258 } else { | 260 } else { |
259 ++it; | 261 ++it; |
260 } | 262 } |
261 } | 263 } |
262 } | 264 } |
263 | 265 |
264 void StorageTypeObservers::RemoveObserverForFilter( | 266 void StorageTypeObservers::RemoveObserverForFilter( |
265 StorageObserver* observer, const StorageObserver::Filter& filter) { | 267 StorageObserver* observer, |
| 268 const StorageObserver::Filter& filter) { |
266 std::string host = net::GetHostOrSpecFromURL(filter.origin); | 269 std::string host = net::GetHostOrSpecFromURL(filter.origin); |
267 HostObserversMap::iterator it = host_observers_map_.find(host); | 270 HostObserversMap::iterator it = host_observers_map_.find(host); |
268 if (it == host_observers_map_.end()) | 271 if (it == host_observers_map_.end()) |
269 return; | 272 return; |
270 | 273 |
271 it->second->RemoveObserver(observer); | 274 it->second->RemoveObserver(observer); |
272 if (!it->second->ContainsObservers()) { | 275 if (!it->second->ContainsObservers()) { |
273 delete it->second; | 276 delete it->second; |
274 host_observers_map_.erase(it); | 277 host_observers_map_.erase(it); |
275 } | 278 } |
276 } | 279 } |
277 | 280 |
278 const HostStorageObservers* StorageTypeObservers::GetHostObservers( | 281 const HostStorageObservers* StorageTypeObservers::GetHostObservers( |
279 const std::string& host) const { | 282 const std::string& host) const { |
280 HostObserversMap::const_iterator it = host_observers_map_.find(host); | 283 HostObserversMap::const_iterator it = host_observers_map_.find(host); |
281 if (it != host_observers_map_.end()) | 284 if (it != host_observers_map_.end()) |
282 return it->second; | 285 return it->second; |
283 | 286 |
284 return NULL; | 287 return NULL; |
285 } | 288 } |
286 | 289 |
287 void StorageTypeObservers::NotifyUsageChange( | 290 void StorageTypeObservers::NotifyUsageChange( |
288 const StorageObserver::Filter& filter, int64 delta) { | 291 const StorageObserver::Filter& filter, |
| 292 int64 delta) { |
289 std::string host = net::GetHostOrSpecFromURL(filter.origin); | 293 std::string host = net::GetHostOrSpecFromURL(filter.origin); |
290 HostObserversMap::iterator it = host_observers_map_.find(host); | 294 HostObserversMap::iterator it = host_observers_map_.find(host); |
291 if (it == host_observers_map_.end()) | 295 if (it == host_observers_map_.end()) |
292 return; | 296 return; |
293 | 297 |
294 it->second->NotifyUsageChange(filter, delta); | 298 it->second->NotifyUsageChange(filter, delta); |
295 } | 299 } |
296 | 300 |
297 | |
298 // StorageMonitor: | 301 // StorageMonitor: |
299 | 302 |
300 StorageMonitor::StorageMonitor(QuotaManager* quota_manager) | 303 StorageMonitor::StorageMonitor(QuotaManager* quota_manager) |
301 : quota_manager_(quota_manager) { | 304 : quota_manager_(quota_manager) { |
302 } | 305 } |
303 | 306 |
304 StorageMonitor::~StorageMonitor() { | 307 StorageMonitor::~StorageMonitor() { |
305 STLDeleteValues(&storage_type_observers_map_); | 308 STLDeleteValues(&storage_type_observers_map_); |
306 } | 309 } |
307 | 310 |
308 void StorageMonitor::AddObserver( | 311 void StorageMonitor::AddObserver(StorageObserver* observer, |
309 StorageObserver* observer, const StorageObserver::MonitorParams& params) { | 312 const StorageObserver::MonitorParams& params) { |
310 DCHECK(observer); | 313 DCHECK(observer); |
311 | 314 |
312 // Check preconditions. | 315 // Check preconditions. |
313 if (params.filter.storage_type == kStorageTypeUnknown || | 316 if (params.filter.storage_type == kStorageTypeUnknown || |
314 params.filter.storage_type == kStorageTypeQuotaNotManaged || | 317 params.filter.storage_type == kStorageTypeQuotaNotManaged || |
315 params.filter.origin.is_empty()) { | 318 params.filter.origin.is_empty()) { |
316 NOTREACHED(); | 319 NOTREACHED(); |
317 return; | 320 return; |
318 } | 321 } |
319 | 322 |
320 StorageTypeObservers* type_observers = NULL; | 323 StorageTypeObservers* type_observers = NULL; |
321 StorageTypeObserversMap::iterator it = | 324 StorageTypeObserversMap::iterator it = |
322 storage_type_observers_map_.find(params.filter.storage_type); | 325 storage_type_observers_map_.find(params.filter.storage_type); |
323 if (it == storage_type_observers_map_.end()) { | 326 if (it == storage_type_observers_map_.end()) { |
324 type_observers = new StorageTypeObservers(quota_manager_); | 327 type_observers = new StorageTypeObservers(quota_manager_); |
325 storage_type_observers_map_[params.filter.storage_type] = type_observers; | 328 storage_type_observers_map_[params.filter.storage_type] = type_observers; |
326 } else { | 329 } else { |
327 type_observers = it->second; | 330 type_observers = it->second; |
328 } | 331 } |
329 | 332 |
330 type_observers->AddObserver(observer, params); | 333 type_observers->AddObserver(observer, params); |
331 } | 334 } |
332 | 335 |
333 void StorageMonitor::RemoveObserver(StorageObserver* observer) { | 336 void StorageMonitor::RemoveObserver(StorageObserver* observer) { |
334 for (StorageTypeObserversMap::iterator it = | 337 for (StorageTypeObserversMap::iterator it = |
335 storage_type_observers_map_.begin(); | 338 storage_type_observers_map_.begin(); |
336 it != storage_type_observers_map_.end(); ++it) { | 339 it != storage_type_observers_map_.end(); |
| 340 ++it) { |
337 it->second->RemoveObserver(observer); | 341 it->second->RemoveObserver(observer); |
338 } | 342 } |
339 } | 343 } |
340 | 344 |
341 void StorageMonitor::RemoveObserverForFilter( | 345 void StorageMonitor::RemoveObserverForFilter( |
342 StorageObserver* observer, const StorageObserver::Filter& filter) { | 346 StorageObserver* observer, |
| 347 const StorageObserver::Filter& filter) { |
343 StorageTypeObserversMap::iterator it = | 348 StorageTypeObserversMap::iterator it = |
344 storage_type_observers_map_.find(filter.storage_type); | 349 storage_type_observers_map_.find(filter.storage_type); |
345 if (it == storage_type_observers_map_.end()) | 350 if (it == storage_type_observers_map_.end()) |
346 return; | 351 return; |
347 | 352 |
348 it->second->RemoveObserverForFilter(observer, filter); | 353 it->second->RemoveObserverForFilter(observer, filter); |
349 } | 354 } |
350 | 355 |
351 const StorageTypeObservers* StorageMonitor::GetStorageTypeObservers( | 356 const StorageTypeObservers* StorageMonitor::GetStorageTypeObservers( |
352 StorageType storage_type) const { | 357 StorageType storage_type) const { |
353 StorageTypeObserversMap::const_iterator it = | 358 StorageTypeObserversMap::const_iterator it = |
354 storage_type_observers_map_.find(storage_type); | 359 storage_type_observers_map_.find(storage_type); |
355 if (it != storage_type_observers_map_.end()) | 360 if (it != storage_type_observers_map_.end()) |
356 return it->second; | 361 return it->second; |
357 | 362 |
358 return NULL; | 363 return NULL; |
359 } | 364 } |
360 | 365 |
361 void StorageMonitor::NotifyUsageChange( | 366 void StorageMonitor::NotifyUsageChange(const StorageObserver::Filter& filter, |
362 const StorageObserver::Filter& filter, int64 delta) { | 367 int64 delta) { |
363 // Check preconditions. | 368 // Check preconditions. |
364 if (filter.storage_type == kStorageTypeUnknown || | 369 if (filter.storage_type == kStorageTypeUnknown || |
365 filter.storage_type == kStorageTypeQuotaNotManaged || | 370 filter.storage_type == kStorageTypeQuotaNotManaged || |
366 filter.origin.is_empty()) { | 371 filter.origin.is_empty()) { |
367 NOTREACHED(); | 372 NOTREACHED(); |
368 return; | 373 return; |
369 } | 374 } |
370 | 375 |
371 StorageTypeObserversMap::iterator it = | 376 StorageTypeObserversMap::iterator it = |
372 storage_type_observers_map_.find(filter.storage_type); | 377 storage_type_observers_map_.find(filter.storage_type); |
373 if (it == storage_type_observers_map_.end()) | 378 if (it == storage_type_observers_map_.end()) |
374 return; | 379 return; |
375 | 380 |
376 it->second->NotifyUsageChange(filter, delta); | 381 it->second->NotifyUsageChange(filter, delta); |
377 } | 382 } |
378 | 383 |
379 } // namespace quota | 384 } // namespace quota |
OLD | NEW |