14f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov// Copyright 2013 The Chromium Authors. All rights reserved. 28530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// Use of this source code is governed by a BSD-style license that can be 38530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// found in the LICENSE file. 48530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany 58530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include "storage/browser/quota/usage_tracker.h" 68530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany 78530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include <algorithm> 88530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include <deque> 98530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include <set> 108530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include <string> 118530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include <vector> 128530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany 138530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include "base/bind.h" 148530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include "base/message_loop/message_loop_proxy.h" 158530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include "base/stl_util.h" 165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include "net/base/net_util.h" 178530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include "storage/browser/quota/storage_monitor.h" 188530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany#include "storage/browser/quota/storage_observer.h" 190586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov 20c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryanynamespace storage { 21c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany 2267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukovnamespace { 23c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany 2414dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukovtypedef ClientUsageTracker::OriginUsageAccumulator OriginUsageAccumulator; 255e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonovtypedef ClientUsageTracker::OriginSetByHost OriginSetByHost; 265e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov 2711f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukovvoid DidGetOriginUsage(const OriginUsageAccumulator& accumulator, 285cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov const GURL& origin, 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines int64 usage) { 308530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany accumulator.Run(origin, usage); 316afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany} 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid DidGetHostUsage(const UsageCallback& callback, 3474737d595c4e3638b980bd88b0492247ae4318faAlexey Samsonov int64 limited_usage, 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines int64 unlimited_usage) { 36b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany DCHECK_GE(limited_usage, 0); 37996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov DCHECK_GE(unlimited_usage, 0); 38996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov callback.Run(limited_usage + unlimited_usage); 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 40348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov 41348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanovbool EraseOriginFromOriginSet(OriginSetByHost* origins_by_host, 42348bd12af55f560e0822e753788d8a51fa050c3fEvgeniy Stepanov const std::string& host, 430586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov const GURL& origin) { 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines OriginSetByHost::iterator found = origins_by_host->find(host); 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (found == origins_by_host->end()) 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return false; 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!found->second.erase(origin)) 490586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov return false; 500586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov 5167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov if (found->second.empty()) 525cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov origins_by_host->erase(host); 535e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov return true; 545e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov} 555e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov 565cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukovbool OriginSetContainsOrigin(const OriginSetByHost& origins, 575e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov const std::string& host, 585e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov const GURL& origin) { 595e2d3776a314629680921abd1d55d89d95a2da90Alexey Samsonov OriginSetByHost::const_iterator itr = origins.find(host); 605cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov return itr != origins.end() && ContainsKey(itr->second, origin); 6167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov} 6267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov 6311f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukovvoid DidGetGlobalUsageForLimitedGlobalUsage(const UsageCallback& callback, 6411f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov int64 total_global_usage, 6511f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov int64 global_unlimited_usage) { 6611f5309ec1bf13430c8a3a16f177d9e8e1190e38Dmitry Vyukov callback.Run(total_global_usage - global_unlimited_usage); 672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} // namespace 702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// UsageTracker ---------------------------------------------------------- 722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUsageTracker::UsageTracker(const QuotaClientList& clients, 742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines StorageType type, 752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines SpecialStoragePolicy* special_storage_policy, 762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines StorageMonitor* storage_monitor) 772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines : type_(type), 782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines storage_monitor_(storage_monitor), 792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines weak_factory_(this) { 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (QuotaClientList::const_iterator iter = clients.begin(); 812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines iter != clients.end(); 822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ++iter) { 832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if ((*iter)->DoesSupport(type)) { 842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines client_tracker_map_[(*iter)->id()] = 852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines new ClientUsageTracker(this, *iter, type, special_storage_policy, 862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines storage_monitor_); 872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUsageTracker::~UsageTracker() { 922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines STLDeleteValues(&client_tracker_map_); 932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesClientUsageTracker* UsageTracker::GetClientTracker(QuotaClient::ID client_id) { 962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ClientTrackerMap::iterator found = client_tracker_map_.find(client_id); 972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (found != client_tracker_map_.end()) 982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return found->second; 992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return NULL; 1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid UsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { 1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (global_usage_callbacks_.HasCallbacks()) { 1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines global_usage_callbacks_.Add(base::Bind( 1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines &DidGetGlobalUsageForLimitedGlobalUsage, callback)); 1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return; 1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 1082d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1092d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!global_limited_usage_callbacks_.Add(callback)) 1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return; 1112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines AccumulateInfo* info = new AccumulateInfo; 1132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Calling GetGlobalLimitedUsage(accumulator) may synchronously 1142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // return if the usage is cached, which may in turn dispatch 1152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // the completion callback before we finish looping over 1162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // all clients (because info->pending_clients may reach 0 1172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // during the loop). 1182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // To avoid this, we add one more pending client as a sentinel 1192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // and fire the sentinel callback at the end. 1202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines info->pending_clients = client_tracker_map_.size() + 1; 1212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines UsageCallback accumulator = base::Bind( 1222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines &UsageTracker::AccumulateClientGlobalLimitedUsage, 1232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines weak_factory_.GetWeakPtr(), base::Owned(info)); 1242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); 1262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines iter != client_tracker_map_.end(); 1272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ++iter) 1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines iter->second->GetGlobalLimitedUsage(accumulator); 1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Fire the sentinel as we've now called GetGlobalUsage for all clients. 1312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines accumulator.Run(0); 1322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid UsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { 1352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (!global_usage_callbacks_.Add(callback)) 1362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return; 1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines AccumulateInfo* info = new AccumulateInfo; 1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Calling GetGlobalUsage(accumulator) may synchronously 1402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // return if the usage is cached, which may in turn dispatch 1412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // the completion callback before we finish looping over 1422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // all clients (because info->pending_clients may reach 0 1432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // during the loop). 1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // To avoid this, we add one more pending client as a sentinel 1452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // and fire the sentinel callback at the end. 1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines info->pending_clients = client_tracker_map_.size() + 1; 1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GlobalUsageCallback accumulator = base::Bind( 1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines &UsageTracker::AccumulateClientGlobalUsage, weak_factory_.GetWeakPtr(), 1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines base::Owned(info)); 1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); 1522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines iter != client_tracker_map_.end(); 1532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ++iter) 1542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines iter->second->GetGlobalUsage(accumulator); 1552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 15667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov // Fire the sentinel as we've now called GetGlobalUsage for all clients. 15767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov accumulator.Run(0, 0); 15867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov} 15967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov 16067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonovvoid UsageTracker::GetHostUsage(const std::string& host, 16167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov const UsageCallback& callback) { 16267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov if (!host_usage_callbacks_.Add(host, callback)) 16367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov return; 16467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov 16567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov AccumulateInfo* info = new AccumulateInfo; 166a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov // Calling GetHostUsage(accumulator) may synchronously 16767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov // return if the usage is cached, which may in turn dispatch 16867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov // the completion callback before we finish looping over 16967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov // all clients (because info->pending_clients may reach 0 17067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov // during the loop). 17167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov // To avoid this, we add one more pending client as a sentinel 17267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov // and fire the sentinel callback at the end. 17367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov info->pending_clients = client_tracker_map_.size() + 1; 17467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov UsageCallback accumulator = base::Bind( 17567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov &UsageTracker::AccumulateClientHostUsage, weak_factory_.GetWeakPtr(), 17667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov base::Owned(info), host); 17767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov 17867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov for (ClientTrackerMap::iterator iter = client_tracker_map_.begin(); 17967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov iter != client_tracker_map_.end(); 18067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov ++iter) 18167505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov iter->second->GetHostUsage(host, accumulator); 18267505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov 18367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov // Fire the sentinel as we've now called GetHostUsage for all clients. 18467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov accumulator.Run(0); 18567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov} 18667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov 18767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonovvoid UsageTracker::UpdateUsageCache( 18867505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov QuotaClient::ID client_id, const GURL& origin, int64 delta) { 18967505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov ClientUsageTracker* client_tracker = GetClientTracker(client_id); 19067505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov DCHECK(client_tracker); 191a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov client_tracker->UpdateUsageCache(origin, delta); 192a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov} 19367505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov 19467505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonovvoid UsageTracker::GetCachedHostsUsage( 19567505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov std::map<std::string, int64>* host_usage) const { 19667505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov DCHECK(host_usage); 19767505a8a0cf9621243ed21b67dfa041224c78e4bAlexey Samsonov host_usage->clear(); 198be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); 199be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov iter != client_tracker_map_.end(); ++iter) { 200be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov iter->second->GetCachedHostsUsage(host_usage); 201be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov } 202be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov} 203be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov 204be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukovvoid UsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { 205be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov DCHECK(origins); 206be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov origins->clear(); 207be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin(); 208be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov iter != client_tracker_map_.end(); ++iter) { 209be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov iter->second->GetCachedOrigins(origins); 210a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov } 211be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov} 212be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov 213a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanovvoid UsageTracker::SetUsageCacheEnabled(QuotaClient::ID client_id, 214be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov const GURL& origin, 215be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov bool enabled) { 216be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov ClientUsageTracker* client_tracker = GetClientTracker(client_id); 217be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov DCHECK(client_tracker); 218be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov 219be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov client_tracker->SetUsageCacheEnabled(origin, enabled); 220be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov} 221be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov 222be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukovvoid UsageTracker::AccumulateClientGlobalLimitedUsage(AccumulateInfo* info, 223be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov int64 limited_usage) { 224be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov info->usage += limited_usage; 225be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov if (--info->pending_clients) 226be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov return; 227be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov 228a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov // All the clients have returned their usage data. Dispatch the 229be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov // pending callbacks. 230be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov global_limited_usage_callbacks_.Run(MakeTuple(info->usage)); 231be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov} 232be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov 233be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukovvoid UsageTracker::AccumulateClientGlobalUsage(AccumulateInfo* info, 234be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov int64 usage, 235a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov int64 unlimited_usage) { 236a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov info->usage += usage; 237be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov info->unlimited_usage += unlimited_usage; 238be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov if (--info->pending_clients) 239be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov return; 240be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov 241be52366ff2500f11133fd6089f349e93bd5f4822Dmitry Vyukov // Defend against confusing inputs from clients. 2422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (info->usage < 0) 2432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines info->usage = 0; 2442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // TODO(michaeln): The unlimited number is not trustworthy, it 2462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // can get out of whack when apps are installed or uninstalled. 2472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (info->unlimited_usage > info->usage) 2482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines info->unlimited_usage = info->usage; 2492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines else if (info->unlimited_usage < 0) 2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines info->unlimited_usage = 0; 2512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // All the clients have returned their usage data. Dispatch the 2532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // pending callbacks. 2542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines global_usage_callbacks_.Run(MakeTuple(info->usage, info->unlimited_usage)); 2552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 2562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid UsageTracker::AccumulateClientHostUsage(AccumulateInfo* info, 2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines const std::string& host, 2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines int64 usage) { 2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines info->usage += usage; 2612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (--info->pending_clients) 2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return; 2632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // Defend against confusing inputs from clients. 2652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (info->usage < 0) 2662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines info->usage = 0; 2672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // All the clients have returned their usage data. Dispatch the 2692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // pending callbacks. 2707cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov host_usage_callbacks_.Run(host, MakeTuple(info->usage)); 2717cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov} 2727cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov 2737cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov// ClientUsageTracker ---------------------------------------------------- 2745d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 2757cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovClientUsageTracker::ClientUsageTracker( 2765d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines UsageTracker* tracker, QuotaClient* client, StorageType type, 2777cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov SpecialStoragePolicy* special_storage_policy, 2787cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov StorageMonitor* storage_monitor) 2797cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov : tracker_(tracker), 280a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov client_(client), 281ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov type_(type), 282ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov storage_monitor_(storage_monitor), 283a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov global_limited_usage_(0), 284ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov global_unlimited_usage_(0), 285ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov global_usage_retrieved_(false), 2867cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov special_storage_policy_(special_storage_policy) { 2877cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov DCHECK(tracker_); 2887cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov DCHECK(client_); 2895d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (special_storage_policy_.get()) 2905d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines special_storage_policy_->AddObserver(this); 2915d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines} 2927cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov 2937cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy StepanovClientUsageTracker::~ClientUsageTracker() { 2947cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov if (special_storage_policy_.get()) 2957cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov special_storage_policy_->RemoveObserver(this); 2967cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov} 2977cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov 2987cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanovvoid ClientUsageTracker::GetGlobalLimitedUsage(const UsageCallback& callback) { 2997cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov if (!global_usage_retrieved_) { 3005d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines GetGlobalUsage(base::Bind(&DidGetGlobalUsageForLimitedGlobalUsage, 3015d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines callback)); 3025d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines return; 3037cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov } 3047cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov 3057cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov if (non_cached_limited_origins_by_host_.empty()) { 3067cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov callback.Run(global_limited_usage_); 3077cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov return; 308a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov } 309a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 310a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov AccumulateInfo* info = new AccumulateInfo; 3117cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov info->pending_jobs = non_cached_limited_origins_by_host_.size() + 1; 312ff5d1fcdd74036fa15d96fafd487397ebf5f202eAlexey Samsonov UsageCallback accumulator = base::Bind( 313a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov &ClientUsageTracker::AccumulateLimitedOriginUsage, AsWeakPtr(), 3147cbbb2943527ff852bdace822c8592cfc7e450d7Evgeniy Stepanov base::Owned(info), callback); 315b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 316b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov for (OriginSetByHost::iterator host_itr = 317b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov non_cached_limited_origins_by_host_.begin(); 318b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov host_itr != non_cached_limited_origins_by_host_.end(); ++host_itr) { 319b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov for (std::set<GURL>::iterator origin_itr = host_itr->second.begin(); 320b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov origin_itr != host_itr->second.end(); ++origin_itr) 321b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov client_->GetOriginUsage(*origin_itr, type_, accumulator); 322b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } 323b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 324b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov accumulator.Run(global_limited_usage_); 325b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov} 326b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 327b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovvoid ClientUsageTracker::GetGlobalUsage(const GlobalUsageCallback& callback) { 328b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (global_usage_retrieved_ && 329b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov non_cached_limited_origins_by_host_.empty() && 330b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov non_cached_unlimited_origins_by_host_.empty()) { 331b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov callback.Run(global_limited_usage_ + global_unlimited_usage_, 332b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov global_unlimited_usage_); 333b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov return; 334b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } 335b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 3368ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov client_->GetOriginsForType(type_, base::Bind( 3376afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany &ClientUsageTracker::DidGetOriginsForGlobalUsage, AsWeakPtr(), 33844be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov callback)); 339996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov} 34067f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov 3415d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesvoid ClientUsageTracker::GetHostUsage( 3425d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines const std::string& host, const UsageCallback& callback) { 3435d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (ContainsKey(cached_hosts_, host) && 3446afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany !ContainsKey(non_cached_limited_origins_by_host_, host) && 345a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov !ContainsKey(non_cached_unlimited_origins_by_host_, host)) { 346a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov // TODO(kinuko): Drop host_usage_map_ cache periodically. 3478530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany callback.Run(GetCachedHostUsage(host)); 3488530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany return; 349a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov } 350c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany 35144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov if (!host_usage_accumulators_.Add( 3528ffd87791a5376d44edfa288cbf469702edbfa22Alexey Samsonov host, base::Bind(&DidGetHostUsage, callback))) 3538530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany return; 354c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov client_->GetOriginsForHost(type_, host, base::Bind( 3556afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany &ClientUsageTracker::DidGetOriginsForHostUsage, AsWeakPtr(), host)); 35644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov} 357996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 35867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukovvoid ClientUsageTracker::UpdateUsageCache( 3595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines const GURL& origin, int64 delta) { 3605d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines std::string host = net::GetHostOrSpecFromURL(origin); 3615d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (cached_hosts_.find(host) != cached_hosts_.end()) { 3626afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany if (!IsUsageCacheEnabledForOrigin(origin)) 363a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov return; 364a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 3658530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany cached_usage_by_host_[host][origin] += delta; 3668530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany if (IsStorageUnlimited(origin)) 367a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov global_unlimited_usage_ += delta; 368c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany else 36944be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov global_limited_usage_ += delta; 370c333dffb81f1d85483d657c254c17f636ab192c5Alexey Samsonov DCHECK_GE(cached_usage_by_host_[host][origin], 0); 3718530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany DCHECK_GE(global_limited_usage_, 0); 372b1cc4e448f35515e737ac4969aaa04f3fa3af10aKostya Serebryany 3736afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany // Notify the usage monitor that usage has changed. The storage monitor may 37444be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov // be NULL during tests. 375996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov if (storage_monitor_) { 37667f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov StorageObserver::Filter filter(type_, origin); 3775d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines storage_monitor_->NotifyUsageChange(filter, delta); 3785d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines } 3795d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines return; 3806afa1b0406f5cce7256d4f8717bfe394a16999b5Kostya Serebryany } 381a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 382a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov // We don't know about this host yet, so populate our cache for it. 3838530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany GetHostUsage(host, base::Bind(&ClientUsageTracker::DidGetHostUsageAfterUpdate, 3848530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany AsWeakPtr(), origin)); 385a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov} 386c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany 38744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanovvoid ClientUsageTracker::GetCachedHostsUsage( 3881f5e23e3204961456d4c7a9b45060597d4ff69afAlexander Potapenko std::map<std::string, int64>* host_usage) const { 3898530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany DCHECK(host_usage); 390b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); 391b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov host_iter != cached_usage_by_host_.end(); host_iter++) { 392b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov const std::string& host = host_iter->first; 393b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov (*host_usage)[host] += GetCachedHostUsage(host); 394b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } 39567f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov} 396b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 397b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovvoid ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const { 398b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov DCHECK(origins); 399b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov for (HostUsageMap::const_iterator host_iter = cached_usage_by_host_.begin(); 400b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov host_iter != cached_usage_by_host_.end(); host_iter++) { 401a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov const UsageMap& origin_map = host_iter->second; 402b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov for (UsageMap::const_iterator origin_iter = origin_map.begin(); 403b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov origin_iter != origin_map.end(); origin_iter++) { 404b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov origins->insert(origin_iter->first); 405b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } 406b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } 407b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov} 408b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 409b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovvoid ClientUsageTracker::SetUsageCacheEnabled(const GURL& origin, 410b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov bool enabled) { 41167f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov std::string host = net::GetHostOrSpecFromURL(origin); 412b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (!enabled) { 413b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov // Erase |origin| from cache and subtract its usage. 414b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov HostUsageMap::iterator found_host = cached_usage_by_host_.find(host); 415b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (found_host != cached_usage_by_host_.end()) { 416b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov UsageMap& cached_usage_for_host = found_host->second; 417a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 418b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov UsageMap::iterator found = cached_usage_for_host.find(origin); 419b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (found != cached_usage_for_host.end()) { 420b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov int64 usage = found->second; 421b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov UpdateUsageCache(origin, -usage); 422b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov cached_usage_for_host.erase(found); 423b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (cached_usage_for_host.empty()) { 424b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov cached_usage_by_host_.erase(found_host); 425b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov cached_hosts_.erase(host); 426b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } 42767f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov } 428b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } 429b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 430b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (IsStorageUnlimited(origin)) 431b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov non_cached_unlimited_origins_by_host_[host].insert(origin); 432b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov else 433a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov non_cached_limited_origins_by_host_[host].insert(origin); 434b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } else { 435b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov // Erase |origin| from |non_cached_origins_| and invalidate the usage cache 436b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov // for the host. 437b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_, 438c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany host, origin) || 439c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_, 44044be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov host, origin)) { 441996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov cached_hosts_.erase(host); 44267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov global_usage_retrieved_ = false; 443a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov } 444c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany } 445b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov} 446a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 447c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryanyvoid ClientUsageTracker::AccumulateLimitedOriginUsage( 448c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany AccumulateInfo* info, 449a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov const UsageCallback& callback, 450153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany int64 usage) { 45144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov info->limited_usage += usage; 452153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany if (--info->pending_jobs) 453153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany return; 454c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany 455f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov callback.Run(info->limited_usage); 45644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov} 457f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov 45867f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukovvoid ClientUsageTracker::DidGetOriginsForGlobalUsage( 459a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov const GlobalUsageCallback& callback, 460f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov const std::set<GURL>& origins) { 461a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov OriginSetByHost origins_by_host; 462c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany for (std::set<GURL>::const_iterator itr = origins.begin(); 463c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany itr != origins.end(); ++itr) 464a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov origins_by_host[net::GetHostOrSpecFromURL(*itr)].insert(*itr); 465153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany 46644be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov AccumulateInfo* info = new AccumulateInfo; 467153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany // Getting host usage may synchronously return the result if the usage is 468153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany // cached, which may in turn dispatch the completion callback before we finish 469c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany // looping over all hosts (because info->pending_jobs may reach 0 during the 470f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov // loop). To avoid this, we add one more pending host as a sentinel and 471f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov // fire the sentinel callback at the end. 47244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov info->pending_jobs = origins_by_host.size() + 1; 473f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov HostUsageAccumulator accumulator = 47467f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov base::Bind(&ClientUsageTracker::AccumulateHostUsage, AsWeakPtr(), 475a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov base::Owned(info), callback); 476f0c846b8ef61a5f4bc664c463d643bb8dedc3768Dmitry Vyukov 477a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov for (OriginSetByHost::iterator itr = origins_by_host.begin(); 478c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany itr != origins_by_host.end(); ++itr) { 479c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany if (host_usage_accumulators_.Add(itr->first, accumulator)) 480a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov GetUsageForOrigins(itr->first, itr->second); 481153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany } 48244be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov 483153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany // Fire the sentinel as we've now called GetUsageForOrigins for all clients. 484153ba3f41d8f6ad1641ae76cfdf01445cec9db89Kostya Serebryany accumulator.Run(0, 0); 485b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov} 486b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 487b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovvoid ClientUsageTracker::AccumulateHostUsage( 488b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov AccumulateInfo* info, 489b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov const GlobalUsageCallback& callback, 49067f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov int64 limited_usage, 491b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov int64 unlimited_usage) { 492b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov info->limited_usage += limited_usage; 493b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov info->unlimited_usage += unlimited_usage; 494b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (--info->pending_jobs) 495b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov return; 496a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 497b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov DCHECK_GE(info->limited_usage, 0); 498b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov DCHECK_GE(info->unlimited_usage, 0); 499b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 500b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov global_usage_retrieved_ = true; 501b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov callback.Run(info->limited_usage + info->unlimited_usage, 502b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov info->unlimited_usage); 503b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov} 504b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 505b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovvoid ClientUsageTracker::DidGetOriginsForHostUsage( 50667f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov const std::string& host, 507b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov const std::set<GURL>& origins) { 508b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov GetUsageForOrigins(host, origins); 509b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov} 510b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 511b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanovvoid ClientUsageTracker::GetUsageForOrigins( 512a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov const std::string& host, 513b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov const std::set<GURL>& origins) { 514b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov AccumulateInfo* info = new AccumulateInfo; 515b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov // Getting origin usage may synchronously return the result if the usage is 516b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov // cached, which may in turn dispatch the completion callback before we finish 517b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov // looping over all origins (because info->pending_jobs may reach 0 during the 518b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov // loop). To avoid this, we add one more pending origin as a sentinel and 519b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov // fire the sentinel callback at the end. 520b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov info->pending_jobs = origins.size() + 1; 521b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov OriginUsageAccumulator accumulator = 52267f5544391c338411b0006bda7dc1b852bbdd4fbDmitry Vyukov base::Bind(&ClientUsageTracker::AccumulateOriginUsage, AsWeakPtr(), 523b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov base::Owned(info), host); 524b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov 525b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov for (std::set<GURL>::const_iterator itr = origins.begin(); 526b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov itr != origins.end(); ++itr) { 527b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov DCHECK_EQ(host, net::GetHostOrSpecFromURL(*itr)); 528a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 529b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov int64 origin_usage = 0; 530b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov if (GetCachedOriginUsage(*itr, &origin_usage)) { 531b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov accumulator.Run(*itr, origin_usage); 532b916e6a9b3efa4907b70a2dcd418c76b044171e7Evgeniy Stepanov } else { 533c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany client_->GetOriginUsage(*itr, type_, base::Bind( 534a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov &DidGetOriginUsage, accumulator, *itr)); 535a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov } 536a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov } 53744be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov 538996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov // Fire the sentinel as we've now called GetOriginUsage for all clients. 539c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany accumulator.Run(GURL(), 0); 540c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany} 541c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany 542c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryanyvoid ClientUsageTracker::AccumulateOriginUsage(AccumulateInfo* info, 54344be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov const std::string& host, 544c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany const GURL& origin, 545996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov int64 usage) { 546c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany if (!origin.is_empty()) { 547c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany if (usage < 0) 548c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany usage = 0; 549a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 550c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany if (IsStorageUnlimited(origin)) 55144be70b186549d592c952a13aafe79bfeae89f81Evgeniy Stepanov info->unlimited_usage += usage; 552a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov else 553fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov info->limited_usage += usage; 554fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov if (IsUsageCacheEnabledForOrigin(origin)) 555fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov AddCachedOrigin(origin, usage); 556fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov } 557fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov if (--info->pending_jobs) 5585d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines return; 5595d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 56015832c2afc4f04fa558160441d1b01fb3f0ec08bAlexander Potapenko AddCachedHost(host); 561fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov host_usage_accumulators_.Run( 5625d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines host, MakeTuple(info->limited_usage, info->unlimited_usage)); 563fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov} 564fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov 565fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanovvoid ClientUsageTracker::DidGetHostUsageAfterUpdate( 566a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov const GURL& origin, int64 usage) { 567fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov if (!storage_monitor_) 568fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov return; 569a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 570fef660506e9e5703fedfee01d614abd4b741c738Evgeniy Stepanov StorageObserver::Filter filter(type_, origin); 5719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov storage_monitor_->NotifyUsageChange(filter, 0); 572cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov} 573cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov 5740586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukovvoid ClientUsageTracker::AddCachedOrigin( 5750586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov const GURL& origin, int64 new_usage) { 5760586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov DCHECK(IsUsageCacheEnabledForOrigin(origin)); 5772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 5780586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov std::string host = net::GetHostOrSpecFromURL(origin); 5790586dcc3e531d43dca6b5d226bac2d38b5ad64feDmitry Vyukov int64* usage = &cached_usage_by_host_[host][origin]; 580cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov int64 delta = new_usage - *usage; 581cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov *usage = new_usage; 5829358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov if (delta) { 5839358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov if (IsStorageUnlimited(origin)) 584cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov global_unlimited_usage_ += delta; 5859358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov else 5869358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov global_limited_usage_ += delta; 587cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov } 5889358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov DCHECK_GE(*usage, 0); 5899358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov DCHECK_GE(global_limited_usage_, 0); 5909358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov} 591cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov 5929358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanovvoid ClientUsageTracker::AddCachedHost(const std::string& host) { 5939358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov cached_hosts_.insert(host); 594cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov} 5959358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov 5969358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanovint64 ClientUsageTracker::GetCachedHostUsage(const std::string& host) const { 597cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov HostUsageMap::const_iterator found = cached_usage_by_host_.find(host); 5989358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov if (found == cached_usage_by_host_.end()) 5999358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov return 0; 6009358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov 601cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov int64 usage = 0; 6029358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov const UsageMap& map = found->second; 6039358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov for (UsageMap::const_iterator iter = map.begin(); 604cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov iter != map.end(); ++iter) { 6059358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov usage += iter->second; 6069358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov } 607cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov return usage; 6089358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov} 6099358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov 6109358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanovbool ClientUsageTracker::GetCachedOriginUsage( 611cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov const GURL& origin, 6129358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov int64* usage) const { 6139358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov std::string host = net::GetHostOrSpecFromURL(origin); 614cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov HostUsageMap::const_iterator found_host = cached_usage_by_host_.find(host); 6159358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov if (found_host == cached_usage_by_host_.end()) 6169358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov return false; 617cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov 6189358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov UsageMap::const_iterator found = found_host->second.find(origin); 6199358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov if (found == found_host->second.end()) 6209358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov return false; 6219358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov 6229358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov DCHECK(IsUsageCacheEnabledForOrigin(origin)); 6239358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov *usage = found->second; 6245d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines return true; 6255d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines} 6265d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 6279358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanovbool ClientUsageTracker::IsUsageCacheEnabledForOrigin( 6289358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov const GURL& origin) const { 6299358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov std::string host = net::GetHostOrSpecFromURL(origin); 6309358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov return !OriginSetContainsOrigin(non_cached_limited_origins_by_host_, 6319358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov host, origin) && 6329358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov !OriginSetContainsOrigin(non_cached_unlimited_origins_by_host_, 6339358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov host, origin); 6349358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov} 6359358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov 6369358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanovvoid ClientUsageTracker::OnGranted(const GURL& origin, 6375d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines int change_flags) { 6385d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines DCHECK(CalledOnValidThread()); 6395d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { 6409358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov int64 usage = 0; 6419358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov if (GetCachedOriginUsage(origin, &usage)) { 6429358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov global_unlimited_usage_ += usage; 6439358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov global_limited_usage_ -= usage; 6449358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov } 6459358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov 6469358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov std::string host = net::GetHostOrSpecFromURL(origin); 647cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov if (EraseOriginFromOriginSet(&non_cached_limited_origins_by_host_, 6489358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov host, origin)) 6499358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov non_cached_unlimited_origins_by_host_[host].insert(origin); 6505d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines } 6515d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines} 6525d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 6539358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanovvoid ClientUsageTracker::OnRevoked(const GURL& origin, 6549358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov int change_flags) { 655cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov DCHECK(CalledOnValidThread()); 6569358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov if (change_flags & SpecialStoragePolicy::STORAGE_UNLIMITED) { 6579358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov int64 usage = 0; 6589358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov if (GetCachedOriginUsage(origin, &usage)) { 6599358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov global_unlimited_usage_ -= usage; 660cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov global_limited_usage_ += usage; 6619358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov } 6629358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov 6635d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines std::string host = net::GetHostOrSpecFromURL(origin); 6645d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (EraseOriginFromOriginSet(&non_cached_unlimited_origins_by_host_, 6655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines host, origin)) 6669358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov non_cached_limited_origins_by_host_[host].insert(origin); 6679358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov } 668cf39032f101dfb3b97b1dfc7b6d03f5d89dff266Evgeniy Stepanov} 6699358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov 6709358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanovvoid ClientUsageTracker::OnCleared() { 6719358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov DCHECK(CalledOnValidThread()); 6729358c58d0aaf1b20f17362af354d4c3c1309276aEvgeniy Stepanov global_limited_usage_ += global_unlimited_usage_; 6732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines global_unlimited_usage_ = 0; 6742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 6752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (OriginSetByHost::const_iterator host_itr = 6762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines non_cached_unlimited_origins_by_host_.begin(); 6772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines host_itr != non_cached_unlimited_origins_by_host_.end(); 6782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ++host_itr) { 6792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (std::set<GURL>::const_iterator origin_itr = host_itr->second.begin(); 6802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines origin_itr != host_itr->second.end(); 6812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ++origin_itr) 6822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines non_cached_limited_origins_by_host_[host_itr->first].insert(*origin_itr); 6832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 6842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines non_cached_unlimited_origins_by_host_.clear(); 6852d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 6862d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 687a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanovbool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const { 688a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov if (type_ == kStorageTypeSyncable) 689a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov return false; 690a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov return special_storage_policy_.get() && 691a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov special_storage_policy_->IsStorageUnlimited(origin); 692a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov} 693a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov 694a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov} // namespace storage 6952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines