| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/quota/usage_tracker.h" | 5 #include "webkit/quota/usage_tracker.h" |
| 6 | 6 |
| 7 #include <algorithm> |
| 7 #include <deque> | 8 #include <deque> |
| 8 #include <set> | 9 #include <set> |
| 9 #include <string> | 10 #include <string> |
| 10 | 11 |
| 11 #include "base/message_loop_proxy.h" | 12 #include "base/message_loop_proxy.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 13 #include "net/base/net_util.h" | 14 #include "net/base/net_util.h" |
| 14 #include "webkit/quota/special_storage_policy.h" | 15 #include "webkit/quota/special_storage_policy.h" |
| 15 | 16 |
| 16 namespace quota { | 17 namespace quota { |
| 17 | 18 |
| 19 namespace { |
| 20 bool SortByHost(const GURL& lhs, const GURL& rhs) { |
| 21 return net::GetHostOrSpecFromURL(lhs) > net::GetHostOrSpecFromURL(rhs); |
| 22 } |
| 23 } |
| 24 |
| 18 // A task class for getting the total amount of data used for a collection of | 25 // A task class for getting the total amount of data used for a collection of |
| 19 // origins. This class is self-destructed. | 26 // origins. This class is self-destructed. |
| 20 class ClientUsageTracker::GatherUsageTaskBase : public QuotaTask { | 27 class ClientUsageTracker::GatherUsageTaskBase : public QuotaTask { |
| 21 public: | 28 public: |
| 22 GatherUsageTaskBase( | 29 GatherUsageTaskBase( |
| 23 UsageTracker* tracker, | 30 UsageTracker* tracker, |
| 24 QuotaClient* client) | 31 QuotaClient* client) |
| 25 : QuotaTask(tracker), | 32 : QuotaTask(tracker), |
| 26 client_(client), | 33 client_(client), |
| 27 tracker_(tracker), | 34 tracker_(tracker), |
| 28 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 35 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 29 DCHECK(tracker_); | 36 DCHECK(tracker_); |
| 30 DCHECK(client_); | 37 DCHECK(client_); |
| 31 client_tracker_ = tracker_->GetClientTracker(client_->id()); | 38 client_tracker_ = tracker_->GetClientTracker(client_->id()); |
| 32 DCHECK(client_tracker_); | 39 DCHECK(client_tracker_); |
| 33 } | 40 } |
| 34 virtual ~GatherUsageTaskBase() {} | 41 virtual ~GatherUsageTaskBase() {} |
| 35 | 42 |
| 36 // Get total usage for the given |origins|. | 43 // Get total usage for the given |origins|. |
| 37 void GetUsageForOrigins(const std::set<GURL>& origins, StorageType type) { | 44 void GetUsageForOrigins(const std::set<GURL>& origins, StorageType type) { |
| 38 DCHECK(original_message_loop()->BelongsToCurrentThread()); | 45 DCHECK(original_message_loop()->BelongsToCurrentThread()); |
| 39 std::set<GURL> origins_to_process; | |
| 40 // We do not get usage for origins for which we have valid usage cache. | 46 // We do not get usage for origins for which we have valid usage cache. |
| 41 client_tracker()->DetermineOriginsToGetUsage(origins, &origins_to_process); | 47 std::vector<GURL> origins_to_gather; |
| 42 if (origins_to_process.empty()) { | 48 std::set<GURL> cached_origins; |
| 49 client_tracker()->GetCachedOrigins(&cached_origins); |
| 50 std::set<GURL> already_added; |
| 51 for (std::set<GURL>::const_iterator iter = origins.begin(); |
| 52 iter != origins.end(); ++iter) { |
| 53 if (cached_origins.find(*iter) == cached_origins.end() && |
| 54 already_added.insert(*iter).second) { |
| 55 origins_to_gather.push_back(*iter); |
| 56 } |
| 57 } |
| 58 if (origins_to_gather.empty()) { |
| 43 CallCompleted(); | 59 CallCompleted(); |
| 44 DeleteSoon(); | 60 DeleteSoon(); |
| 45 return; | 61 return; |
| 46 } | 62 } |
| 47 | 63 |
| 64 // Sort them so we can detect when we've gathered all info for a particular |
| 65 // host in DidGetUsage. |
| 66 std::sort(origins_to_gather.begin(), origins_to_gather.end(), SortByHost); |
| 67 |
| 48 // First, fully populate the pending queue because GetOriginUsage may call | 68 // First, fully populate the pending queue because GetOriginUsage may call |
| 49 // the completion callback immediately. | 69 // the completion callback immediately. |
| 50 for (std::set<GURL>::const_iterator iter = origins_to_process.begin(); | 70 for (std::vector<GURL>::const_iterator iter = origins_to_gather.begin(); |
| 51 iter != origins_to_process.end(); iter++) | 71 iter != origins_to_gather.end(); iter++) |
| 52 pending_origins_.push_back(*iter); | 72 pending_origins_.push_back(*iter); |
| 53 | 73 |
| 54 for (std::set<GURL>::const_iterator iter = origins_to_process.begin(); | 74 for (std::vector<GURL>::const_iterator iter = origins_to_gather.begin(); |
| 55 iter != origins_to_process.end(); iter++) | 75 iter != origins_to_gather.end(); iter++) |
| 56 client_->GetOriginUsage( | 76 client_->GetOriginUsage( |
| 57 *iter, | 77 *iter, |
| 58 tracker_->type(), | 78 tracker_->type(), |
| 59 callback_factory_.NewCallback(&GatherUsageTaskBase::DidGetUsage)); | 79 callback_factory_.NewCallback(&GatherUsageTaskBase::DidGetUsage)); |
| 60 } | 80 } |
| 61 | 81 |
| 62 bool IsOriginDone(const GURL& origin) const { | |
| 63 DCHECK(original_message_loop()->BelongsToCurrentThread()); | |
| 64 return origin_usage_map_.find(origin) != origin_usage_map_.end(); | |
| 65 } | |
| 66 | |
| 67 protected: | 82 protected: |
| 68 virtual void Aborted() OVERRIDE { | 83 virtual void Aborted() OVERRIDE { |
| 69 DeleteSoon(); | 84 DeleteSoon(); |
| 70 } | 85 } |
| 71 | 86 |
| 72 UsageTracker* tracker() const { return tracker_; } | 87 UsageTracker* tracker() const { return tracker_; } |
| 73 ClientUsageTracker* client_tracker() const { return client_tracker_; } | 88 ClientUsageTracker* client_tracker() const { return client_tracker_; } |
| 74 const std::map<GURL, int64>& origin_usage_map() const { | |
| 75 return origin_usage_map_; | |
| 76 } | |
| 77 | 89 |
| 78 private: | 90 private: |
| 79 void DidGetUsage(int64 usage) { | 91 void DidGetUsage(int64 usage) { |
| 92 DCHECK(original_message_loop()->BelongsToCurrentThread()); |
| 93 DCHECK(!pending_origins_.empty()); |
| 94 DCHECK(client_tracker_); |
| 95 |
| 80 // Defend against confusing inputs from QuotaClients. | 96 // Defend against confusing inputs from QuotaClients. |
| 81 DCHECK_GE(usage, 0); | 97 DCHECK_GE(usage, 0); |
| 82 if (usage < 0) | 98 if (usage < 0) |
| 83 usage = 0; | 99 usage = 0; |
| 84 | 100 |
| 85 // This code assumes DidGetUsage callbacks are called in the same | 101 // This code assumes DidGetUsage callbacks are called in the same |
| 86 // order as we dispatched GetOriginUsage calls. | 102 // order as we dispatched GetOriginUsage calls. |
| 87 DCHECK(original_message_loop()->BelongsToCurrentThread()); | 103 const GURL& origin = pending_origins_.front(); |
| 88 DCHECK(!pending_origins_.empty()); | 104 std::string host = net::GetHostOrSpecFromURL(origin); |
| 89 origin_usage_map_[pending_origins_.front()] = usage; | 105 client_tracker_->AddCachedOrigin(origin, usage); |
| 106 |
| 90 pending_origins_.pop_front(); | 107 pending_origins_.pop_front(); |
| 108 if (pending_origins_.empty() || |
| 109 host != net::GetHostOrSpecFromURL(pending_origins_.front())) { |
| 110 client_tracker_->AddCachedHost(host); |
| 111 } |
| 112 |
| 91 if (pending_origins_.empty()) { | 113 if (pending_origins_.empty()) { |
| 92 // We're done. | 114 // We're done. |
| 93 CallCompleted(); | 115 CallCompleted(); |
| 94 DeleteSoon(); | 116 DeleteSoon(); |
| 95 } | 117 } |
| 96 } | 118 } |
| 97 | 119 |
| 98 QuotaClient* client_; | 120 QuotaClient* client_; |
| 99 UsageTracker* tracker_; | 121 UsageTracker* tracker_; |
| 100 ClientUsageTracker* client_tracker_; | 122 ClientUsageTracker* client_tracker_; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 122 virtual ~GatherGlobalUsageTask() {} | 144 virtual ~GatherGlobalUsageTask() {} |
| 123 | 145 |
| 124 protected: | 146 protected: |
| 125 virtual void Run() OVERRIDE { | 147 virtual void Run() OVERRIDE { |
| 126 client_->GetOriginsForType(tracker()->type(), | 148 client_->GetOriginsForType(tracker()->type(), |
| 127 callback_factory_.NewCallback( | 149 callback_factory_.NewCallback( |
| 128 &GatherUsageTaskBase::GetUsageForOrigins)); | 150 &GatherUsageTaskBase::GetUsageForOrigins)); |
| 129 } | 151 } |
| 130 | 152 |
| 131 virtual void Completed() OVERRIDE { | 153 virtual void Completed() OVERRIDE { |
| 132 client_tracker()->DidGetGlobalUsage(origin_usage_map()); | 154 client_tracker()->GatherGlobalUsageComplete(); |
| 133 } | 155 } |
| 134 | 156 |
| 135 private: | 157 private: |
| 136 QuotaClient* client_; | 158 QuotaClient* client_; |
| 137 base::ScopedCallbackFactory<GatherUsageTaskBase> callback_factory_; | 159 base::ScopedCallbackFactory<GatherUsageTaskBase> callback_factory_; |
| 138 | 160 |
| 139 DISALLOW_COPY_AND_ASSIGN(GatherGlobalUsageTask); | 161 DISALLOW_COPY_AND_ASSIGN(GatherGlobalUsageTask); |
| 140 }; | 162 }; |
| 141 | 163 |
| 142 // A task class for getting the total amount of data used for a given host. | 164 // A task class for getting the total amount of data used for a given host. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 157 virtual ~GatherHostUsageTask() {} | 179 virtual ~GatherHostUsageTask() {} |
| 158 | 180 |
| 159 protected: | 181 protected: |
| 160 virtual void Run() OVERRIDE { | 182 virtual void Run() OVERRIDE { |
| 161 client_->GetOriginsForHost(tracker()->type(), host_, | 183 client_->GetOriginsForHost(tracker()->type(), host_, |
| 162 callback_factory_.NewCallback( | 184 callback_factory_.NewCallback( |
| 163 &GatherUsageTaskBase::GetUsageForOrigins)); | 185 &GatherUsageTaskBase::GetUsageForOrigins)); |
| 164 } | 186 } |
| 165 | 187 |
| 166 virtual void Completed() OVERRIDE { | 188 virtual void Completed() OVERRIDE { |
| 167 client_tracker()->DidGetHostUsage(host_, origin_usage_map()); | 189 client_tracker()->GatherHostUsageComplete(host_); |
| 168 } | 190 } |
| 169 | 191 |
| 170 private: | 192 private: |
| 171 QuotaClient* client_; | 193 QuotaClient* client_; |
| 172 std::string host_; | 194 std::string host_; |
| 173 base::ScopedCallbackFactory<GatherUsageTaskBase> callback_factory_; | 195 base::ScopedCallbackFactory<GatherUsageTaskBase> callback_factory_; |
| 174 | 196 |
| 175 DISALLOW_COPY_AND_ASSIGN(GatherHostUsageTask); | 197 DISALLOW_COPY_AND_ASSIGN(GatherHostUsageTask); |
| 176 }; | 198 }; |
| 177 | 199 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 QuotaClient::ID client_id, const GURL& origin, int64 delta) { | 270 QuotaClient::ID client_id, const GURL& origin, int64 delta) { |
| 249 ClientUsageTracker* client_tracker = GetClientTracker(client_id); | 271 ClientUsageTracker* client_tracker = GetClientTracker(client_id); |
| 250 DCHECK(client_tracker); | 272 DCHECK(client_tracker); |
| 251 client_tracker->UpdateUsageCache(origin, delta); | 273 client_tracker->UpdateUsageCache(origin, delta); |
| 252 } | 274 } |
| 253 | 275 |
| 254 void UsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { | 276 void UsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { |
| 255 DCHECK(origins); | 277 DCHECK(origins); |
| 256 origins->clear(); | 278 origins->clear(); |
| 257 for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); | 279 for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); |
| 258 iter != client_tracker_map_.end(); | 280 iter != client_tracker_map_.end(); ++iter) { |
| 259 ++iter) { | 281 iter->second->GetCachedOrigins(origins); |
| 260 const std::set<GURL>& client_origins = iter->second->cached_origins(); | |
| 261 origins->insert(client_origins.begin(), client_origins.end()); | |
| 262 } | 282 } |
| 263 } | 283 } |
| 264 | 284 |
| 265 void UsageTracker::DidGetClientGlobalUsage(StorageType type, | 285 void UsageTracker::DidGetClientGlobalUsage(StorageType type, |
| 266 int64 usage, | 286 int64 usage, |
| 267 int64 unlimited_usage) { | 287 int64 unlimited_usage) { |
| 268 DCHECK_EQ(type, type_); | 288 DCHECK_EQ(type, type_); |
| 269 global_usage_.usage += usage; | 289 global_usage_.usage += usage; |
| 270 global_usage_.unlimited_usage += unlimited_usage; | 290 global_usage_.unlimited_usage += unlimited_usage; |
| 271 if (--global_usage_.pending_clients == 0) { | 291 if (--global_usage_.pending_clients == 0) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 return; | 363 return; |
| 344 } | 364 } |
| 345 DCHECK(!global_usage_callback_.HasCallbacks()); | 365 DCHECK(!global_usage_callback_.HasCallbacks()); |
| 346 global_usage_callback_.Add(callback); | 366 global_usage_callback_.Add(callback); |
| 347 global_usage_task_ = new GatherGlobalUsageTask(tracker_, client_); | 367 global_usage_task_ = new GatherGlobalUsageTask(tracker_, client_); |
| 348 global_usage_task_->Start(); | 368 global_usage_task_->Start(); |
| 349 } | 369 } |
| 350 | 370 |
| 351 void ClientUsageTracker::GetHostUsage( | 371 void ClientUsageTracker::GetHostUsage( |
| 352 const std::string& host, HostUsageCallback* callback) { | 372 const std::string& host, HostUsageCallback* callback) { |
| 353 std::map<std::string, int64>::iterator found = host_usage_map_.find(host); | 373 HostSet::const_iterator found = cached_hosts_.find(host); |
| 354 if (found != host_usage_map_.end()) { | 374 if (found != cached_hosts_.end()) { |
| 355 // TODO(kinuko): Drop host_usage_map_ cache periodically. | 375 // TODO(kinuko): Drop host_usage_map_ cache periodically. |
| 356 callback->Run(host, type_, found->second); | 376 callback->Run(host, type_, GetCachedHostUsage(host)); |
| 357 delete callback; | 377 delete callback; |
| 358 return; | 378 return; |
| 359 } | 379 } |
| 360 DCHECK(!host_usage_callbacks_.HasCallbacks(host)); | 380 if (!host_usage_callbacks_.Add(host, callback) || global_usage_task_) |
| 361 DCHECK(host_usage_tasks_.find(host) == host_usage_tasks_.end()); | |
| 362 host_usage_callbacks_.Add(host, callback); | |
| 363 if (global_usage_task_) | |
| 364 return; | 381 return; |
| 365 GatherHostUsageTask* task = new GatherHostUsageTask(tracker_, client_, host); | 382 GatherHostUsageTask* task = new GatherHostUsageTask(tracker_, client_, host); |
| 366 host_usage_tasks_[host] = task; | 383 host_usage_tasks_[host] = task; |
| 367 task->Start(); | 384 task->Start(); |
| 368 } | 385 } |
| 369 | 386 |
| 370 void ClientUsageTracker::DetermineOriginsToGetUsage( | 387 void ClientUsageTracker::UpdateUsageCache( |
| 371 const std::set<GURL>& origins, std::set<GURL>* origins_to_process) { | 388 const GURL& origin, int64 delta) { |
| 372 DCHECK(origins_to_process); | 389 std::string host = net::GetHostOrSpecFromURL(origin); |
| 373 for (std::set<GURL>::const_iterator iter = origins.begin(); | 390 if (cached_hosts_.find(host) != cached_hosts_.end()) { |
| 374 iter != origins.end(); ++iter) { | 391 cached_usage_[host][origin] += delta; |
| 375 if (cached_origins_.find(*iter) == cached_origins_.end()) | 392 global_usage_ += delta; |
| 376 origins_to_process->insert(*iter); | 393 if (IsStorageUnlimited(origin)) |
| 394 global_unlimited_usage_ += delta; |
| 395 DCHECK_GE(cached_usage_[host][origin], 0); |
| 396 DCHECK_GE(global_usage_, 0); |
| 397 return; |
| 398 } |
| 399 |
| 400 // We don't know about this host yet, so populate our cache for it. |
| 401 GetHostUsage(host, |
| 402 NewCallback(this, &ClientUsageTracker::NoopHostUsageCallback)); |
| 403 } |
| 404 |
| 405 void ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { |
| 406 DCHECK(origins); |
| 407 for (HostUsageMap::const_iterator host_iter = cached_usage_.begin(); |
| 408 host_iter != cached_usage_.end(); host_iter++) { |
| 409 const UsageMap& origin_map = host_iter->second; |
| 410 for (UsageMap::const_iterator origin_iter = origin_map.begin(); |
| 411 origin_iter != origin_map.end(); origin_iter++) { |
| 412 origins->insert(origin_iter->first); |
| 413 } |
| 377 } | 414 } |
| 378 } | 415 } |
| 379 | 416 |
| 380 void ClientUsageTracker::UpdateUsageCache( | 417 void ClientUsageTracker::AddCachedOrigin( |
| 381 const GURL& origin, int64 delta) { | 418 const GURL& origin, int64 usage) { |
| 382 std::string host = net::GetHostOrSpecFromURL(origin); | 419 std::string host = net::GetHostOrSpecFromURL(origin); |
| 383 if (cached_origins_.find(origin) != cached_origins_.end()) { | 420 UsageMap::iterator iter = cached_usage_[host]. |
| 384 host_usage_map_[host] += delta; | 421 insert(UsageMap::value_type(origin, 0)).first; |
| 422 int64 old_usage = iter->second; |
| 423 iter->second = usage; |
| 424 int64 delta = usage - old_usage; |
| 425 if (delta) { |
| 385 global_usage_ += delta; | 426 global_usage_ += delta; |
| 386 if (IsStorageUnlimited(origin)) | 427 if (IsStorageUnlimited(origin)) |
| 387 global_unlimited_usage_ += delta; | 428 global_unlimited_usage_ += delta; |
| 388 DCHECK_GE(host_usage_map_[host], 0); | |
| 389 DCHECK_GE(global_usage_, 0); | |
| 390 return; | |
| 391 } | 429 } |
| 392 if (global_usage_retrieved_ || | 430 DCHECK_GE(iter->second, 0); |
| 393 host_usage_map_.find(host) != host_usage_map_.end()) { | 431 DCHECK_GE(global_usage_, 0); |
| 394 // This might be for a new origin. | |
| 395 cached_origins_.insert(origin); | |
| 396 host_usage_map_[host] += delta; | |
| 397 global_usage_ += delta; | |
| 398 if (IsStorageUnlimited(origin)) | |
| 399 global_unlimited_usage_ += delta; | |
| 400 DCHECK_GE(host_usage_map_[host], 0); | |
| 401 DCHECK_GE(global_usage_, 0); | |
| 402 return; | |
| 403 } | |
| 404 // See if the origin has been processed in outstanding gather tasks | |
| 405 // and add up the delta if it has. | |
| 406 if (global_usage_task_ && global_usage_task_->IsOriginDone(origin)) { | |
| 407 host_usage_map_[host] += delta; | |
| 408 global_usage_ += delta; | |
| 409 if (IsStorageUnlimited(origin)) | |
| 410 global_unlimited_usage_ += delta; | |
| 411 DCHECK_GE(host_usage_map_[host], 0); | |
| 412 DCHECK_GE(global_usage_, 0); | |
| 413 return; | |
| 414 } | |
| 415 if (host_usage_tasks_.find(host) != host_usage_tasks_.end() && | |
| 416 host_usage_tasks_[host]->IsOriginDone(origin)) { | |
| 417 host_usage_map_[host] += delta; | |
| 418 DCHECK_GE(host_usage_map_[host], 0); | |
| 419 } | |
| 420 // Otherwise we have not cached usage info for the origin yet. | |
| 421 // Succeeding GetUsage tasks would eventually catch the change. | |
| 422 } | 432 } |
| 423 | 433 |
| 424 void ClientUsageTracker::DidGetGlobalUsage( | 434 void ClientUsageTracker::AddCachedHost(const std::string& host) { |
| 425 const std::map<GURL, int64>& origin_usage_map) { | 435 cached_hosts_.insert(host); |
| 436 } |
| 437 |
| 438 void ClientUsageTracker::GatherGlobalUsageComplete() { |
| 426 DCHECK(global_usage_task_ != NULL); | 439 DCHECK(global_usage_task_ != NULL); |
| 427 global_usage_task_ = NULL; | 440 global_usage_task_ = NULL; |
| 428 // TODO(kinuko): Record when it has retrieved the global usage. | 441 // TODO(kinuko): Record when it has retrieved the global usage. |
| 429 global_usage_retrieved_ = true; | 442 global_usage_retrieved_ = true; |
| 430 for (std::map<GURL, int64>::const_iterator iter = origin_usage_map.begin(); | |
| 431 iter != origin_usage_map.end(); | |
| 432 ++iter) { | |
| 433 if (cached_origins_.insert(iter->first).second) { | |
| 434 global_usage_ += iter->second; | |
| 435 if (IsStorageUnlimited(iter->first)) | |
| 436 global_unlimited_usage_ += iter->second; | |
| 437 std::string host = net::GetHostOrSpecFromURL(iter->first); | |
| 438 host_usage_map_[host] += iter->second; | |
| 439 DCHECK_GE(host_usage_map_[host], 0); | |
| 440 DCHECK_GE(global_usage_, 0); | |
| 441 } | |
| 442 } | |
| 443 | 443 |
| 444 // Dispatches the global usage callback. | |
| 445 DCHECK(global_usage_callback_.HasCallbacks()); | 444 DCHECK(global_usage_callback_.HasCallbacks()); |
| 446 global_usage_callback_.Run(type_, global_usage_, global_unlimited_usage_); | 445 global_usage_callback_.Run(type_, global_usage_, global_unlimited_usage_); |
| 447 | 446 |
| 448 // Dispatches host usage callbacks. | |
| 449 for (HostUsageCallbackMap::iterator iter = host_usage_callbacks_.Begin(); | 447 for (HostUsageCallbackMap::iterator iter = host_usage_callbacks_.Begin(); |
| 450 iter != host_usage_callbacks_.End(); | 448 iter != host_usage_callbacks_.End(); ++iter) { |
| 451 ++iter) { | 449 iter->second.Run(iter->first, type_, GetCachedHostUsage(iter->first)); |
| 452 std::map<std::string, int64>::iterator found = | |
| 453 host_usage_map_.find(iter->first); | |
| 454 if (found == host_usage_map_.end()) | |
| 455 iter->second.Run(iter->first, type_, 0); | |
| 456 else | |
| 457 iter->second.Run(iter->first, type_, found->second); | |
| 458 } | 450 } |
| 459 host_usage_callbacks_.Clear(); | 451 host_usage_callbacks_.Clear(); |
| 460 } | 452 } |
| 461 | 453 |
| 462 void ClientUsageTracker::DidGetHostUsage( | 454 void ClientUsageTracker::GatherHostUsageComplete(const std::string& host) { |
| 463 const std::string& host, | |
| 464 const std::map<GURL, int64>& origin_usage_map) { | |
| 465 DCHECK(host_usage_tasks_.find(host) != host_usage_tasks_.end()); | 455 DCHECK(host_usage_tasks_.find(host) != host_usage_tasks_.end()); |
| 466 host_usage_tasks_.erase(host); | 456 host_usage_tasks_.erase(host); |
| 467 for (std::map<GURL, int64>::const_iterator iter = origin_usage_map.begin(); | 457 host_usage_callbacks_.Run(host, host, type_, GetCachedHostUsage(host)); |
| 468 iter != origin_usage_map.end(); | 458 } |
| 469 ++iter) { | 459 |
| 470 if (cached_origins_.insert(iter->first).second) { | 460 int64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) { |
| 471 global_usage_ += iter->second; | 461 HostUsageMap::const_iterator found = cached_usage_.find(host); |
| 472 if (IsStorageUnlimited(iter->first)) | 462 if (found == cached_usage_.end()) |
| 473 global_unlimited_usage_ += iter->second; | 463 return 0; |
| 474 host_usage_map_[host] += iter->second; | 464 |
| 475 DCHECK_GE(host_usage_map_[host], 0); | 465 int64 usage = 0; |
| 476 DCHECK_GE(global_usage_, 0); | 466 const UsageMap& map = found->second; |
| 477 } | 467 for (UsageMap::const_iterator iter = map.begin(); |
| 468 iter != map.end(); ++iter) { |
| 469 usage += iter->second; |
| 478 } | 470 } |
| 471 return usage; |
| 472 } |
| 479 | 473 |
| 480 // Dispatches the host usage callback. | 474 void ClientUsageTracker::NoopHostUsageCallback( |
| 481 host_usage_callbacks_.Run(host, host, type_, host_usage_map_[host]); | 475 const std::string& host, StorageType type, int64 usage) { |
| 482 } | 476 } |
| 483 | 477 |
| 484 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { | 478 bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { |
| 485 return special_storage_policy_.get() && | 479 return special_storage_policy_.get() && |
| 486 special_storage_policy_->IsStorageUnlimited(origin); | 480 special_storage_policy_->IsStorageUnlimited(origin); |
| 487 } | 481 } |
| 488 | 482 |
| 489 } // namespace quota | 483 } // namespace quota |
| OLD | NEW |