1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <functional> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/metrics/histogram.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_info.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_database.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager_proxy.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_temporary_storage_evictor.h" 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/storage_monitor.h" 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/usage_tracker.h" 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/quota/quota_types.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UMA_HISTOGRAM_MBYTES(name, sample) \ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS( \ 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (name), static_cast<int>((sample) / kMBytes), \ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, 10 * 1024 * 1024 /* 10TB */, 100) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kMBytes = 1024 * 1024; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinutesInMilliSeconds = 60 * 1000; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kReportHistogramInterval = 60 * 60 * 1000; // 1 hour 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const double kTemporaryQuotaRatioToAvail = 1.0 / 3.0; // 33% 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Arbitrary for now, but must be reasonably small so that 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// in-memory databases can fit. 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// TODO(kinuko): Refer SysInfo::AmountOfPhysicalMemory() to determine this. 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int64 QuotaManager::kIncognitoDefaultQuotaLimit = 100 * kMBytes; 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int64 QuotaManager::kNoLimit = kint64max; 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int QuotaManager::kPerHostTemporaryPortion = 5; // 20% 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Cap size for per-host persistent quota determined by the histogram. 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is a bit lax value because the histogram says nothing about per-host 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// persistent storage usage and we determined by global persistent storage 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// usage that is less than 10GB for almost all users. 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int64 QuotaManager::kPerHostPersistentQuotaLimit = 10 * 1024 * kMBytes; 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char QuotaManager::kDatabaseName[] = "QuotaManager"; 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst int QuotaManager::kThresholdOfErrorsToBeBlacklisted = 3; 68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Preserve kMinimumPreserveForSystem disk space for system book-keeping 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// when returning the quota to unlimited apps/extensions. 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// TODO(kinuko): This should be like 10% of the actual disk space. 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// For now we simply use a constant as getting the disk size needs 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// platform-dependent code. (http://crbug.com/178976) 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochint64 QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes; 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int QuotaManager::kEvictionIntervalInMilliSeconds = 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 30 * kMinutesInMilliSeconds; 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Heuristics: assuming average cloud server allows a few Gigs storage 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// on the server side and the storage needs to be shared for user data 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// and by multiple apps. 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int64 QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes; 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CountOriginType(const std::set<GURL>& origins, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpecialStoragePolicy* policy, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* protected_origins, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* unlimited_origins) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(protected_origins); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(unlimited_origins); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *protected_origins = 0; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *unlimited_origins = 0; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!policy) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<GURL>::const_iterator itr = origins.begin(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) itr != origins.end(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++itr) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy->IsStorageProtected(*itr)) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++*protected_origins; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (policy->IsStorageUnlimited(*itr)) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++*unlimited_origins; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetTemporaryGlobalOverrideQuotaOnDBThread(int64* new_quota, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!database->SetQuotaConfigValue( 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase::kTemporaryQuotaOverrideKey, *new_quota)) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *new_quota = -1; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetPersistentHostQuotaOnDBThread(const std::string& host, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* quota, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) database->GetHostQuota(host, kStorageTypePersistent, quota); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetPersistentHostQuotaOnDBThread(const std::string& host, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* new_quota, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (database->SetHostQuota(host, kStorageTypePersistent, *new_quota)) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *new_quota = 0; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InitializeOnDBThread(int64* temporary_quota_override, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* desired_available_space, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) database->GetQuotaConfigValue(QuotaDatabase::kTemporaryQuotaOverrideKey, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_quota_override); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) database->GetQuotaConfigValue(QuotaDatabase::kDesiredAvailableSpaceKey, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_available_space); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetLRUOriginOnDBThread(StorageType type, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL>* exceptions, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpecialStoragePolicy* policy, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL* url, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) database->GetLRUOrigin(type, *exceptions, policy, url); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeleteOriginInfoOnDBThread(const GURL& origin, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return database->DeleteOriginInfo(origin, type); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (database->IsOriginDatabaseBootstrapped()) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register existing origins with 0 last time access. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (database->RegisterInitialOriginInfo(*origins, kStorageTypeTemporary)) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) database->SetOriginDatabaseBootstrapped(true); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UpdateAccessTimeOnDBThread(const GURL& origin, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time accessed_time, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return database->SetOriginLastAccessTime(origin, type, accessed_time); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UpdateModifiedTimeOnDBThread(const GURL& origin, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time modified_time, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return database->SetOriginLastModifiedTime(origin, type, modified_time); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int64 CallSystemGetAmountOfFreeDiskSpace(const base::FilePath& profile_path) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the profile path exists. 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!base::CreateDirectory(profile_path)) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Create directory failed for path" << profile_path.value(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::SysInfo::AmountOfFreeDiskSpace(profile_path); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int64 CalculateTemporaryGlobalQuota(int64 global_limited_usage, 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 available_space) { 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_GE(global_limited_usage, 0); 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 avail_space = available_space; 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (avail_space < kint64max - global_limited_usage) { 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We basically calculate the temporary quota by 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // [available_space + space_used_for_temp] * kTempQuotaRatio, 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // but make sure we'll have no overflow. 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) avail_space += global_limited_usage; 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return avail_space * kTemporaryQuotaRatioToAvail; 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DispatchTemporaryGlobalQuotaCallback( 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const QuotaCallback& callback, 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) QuotaStatusCode status, 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UsageAndQuota& usage_and_quota) { 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status != kQuotaStatusOk) { 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(status, 0); 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(status, CalculateTemporaryGlobalQuota( 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota.global_limited_usage, 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota.available_disk_space)); 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int64 CalculateQuotaWithDiskSpace( 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 available_disk_space, int64 usage, int64 quota) { 231e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (available_disk_space < QuotaManager::kMinimumPreserveForSystem) { 232e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch LOG(WARNING) 233e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch << "Running out of disk space for profile." 234e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch << " QuotaManager starts forbidding further quota consumption."; 235e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return usage; 236e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 237e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 238e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (quota < usage) { 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No more space; cap the quota to the current usage. 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return usage; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) available_disk_space -= QuotaManager::kMinimumPreserveForSystem; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (available_disk_space < quota - usage) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return available_disk_space + usage; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return quota; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int64 CalculateTemporaryHostQuota(int64 host_usage, 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 global_quota, 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 global_limited_usage) { 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_GE(global_limited_usage, 0); 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 host_quota = global_quota / QuotaManager::kPerHostTemporaryPortion; 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (global_limited_usage > global_quota) 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) host_quota = std::min(host_quota, host_usage); 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return host_quota; 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DispatchUsageAndQuotaForWebApps( 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StorageType type, 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_incognito, 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_unlimited, 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool can_query_disk_size, 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const QuotaManager::GetUsageAndQuotaCallback& callback, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaStatusCode status, 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UsageAndQuota& usage_and_quota) { 26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status != kQuotaStatusOk) { 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(status, 0, 0); 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 usage = usage_and_quota.usage; 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 quota = usage_and_quota.quota; 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (type == kStorageTypeTemporary && !is_unlimited) { 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) quota = CalculateTemporaryHostQuota( 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage, quota, usage_and_quota.global_limited_usage); 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (is_incognito) { 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) quota = std::min(quota, QuotaManager::kIncognitoDefaultQuotaLimit); 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(status, usage, quota); 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // For apps with unlimited permission or can_query_disk_size is true (and not 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // in incognito mode). 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We assume we can expose the actual disk size for them and cap the quota by 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the available disk space. 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_unlimited || can_query_disk_size) { 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run( 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) status, usage, 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CalculateQuotaWithDiskSpace( 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota.available_disk_space, 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage, quota)); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(status, usage, quota); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)UsageAndQuota::UsageAndQuota() 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : usage(0), 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) global_limited_usage(0), 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) quota(0), 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) available_disk_space(0) { 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)UsageAndQuota::UsageAndQuota( 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 usage, 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int64 global_limited_usage, 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 quota, 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 available_disk_space) 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : usage(usage), 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) global_limited_usage(global_limited_usage), 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) quota(quota), 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) available_disk_space(available_disk_space) { 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class UsageAndQuotaCallbackDispatcher 32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : public QuotaTask, 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public base::SupportsWeakPtr<UsageAndQuotaCallbackDispatcher> { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit UsageAndQuotaCallbackDispatcher(QuotaManager* manager) 32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : QuotaTask(manager), 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_usage_(false), 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_global_limited_usage_(false), 33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_quota_(false), 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_available_disk_space_(false), 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) status_(kQuotaStatusUnknown), 33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_(-1, -1, -1, -1), 33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) waiting_callbacks_(1) {} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~UsageAndQuotaCallbackDispatcher() {} 33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void WaitForResults(const QuotaManager::UsageAndQuotaCallback& callback) { 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_ = callback; 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Start(); 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void set_usage(int64 usage) { 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.usage = usage; 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_usage_ = true; 34790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void set_global_limited_usage(int64 global_limited_usage) { 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.global_limited_usage = global_limited_usage; 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_global_limited_usage_ = true; 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void set_quota(int64 quota) { 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.quota = quota; 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_quota_ = true; 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void set_available_disk_space(int64 available_disk_space) { 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.available_disk_space = available_disk_space; 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_available_disk_space_ = true; 36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UsageCallback GetHostUsageCallback() { 36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++waiting_callbacks_; 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_usage_ = true; 36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetHostUsage, 36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AsWeakPtr()); 36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UsageCallback GetGlobalLimitedUsageCallback() { 37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++waiting_callbacks_; 37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_global_limited_usage_ = true; 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return base::Bind( 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &UsageAndQuotaCallbackDispatcher::DidGetGlobalLimitedUsage, 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AsWeakPtr()); 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) QuotaCallback GetQuotaCallback() { 38090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++waiting_callbacks_; 38190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_quota_ = true; 38290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetQuota, 38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AsWeakPtr()); 38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 38690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) QuotaCallback GetAvailableSpaceCallback() { 38790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++waiting_callbacks_; 38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) has_available_disk_space_ = true; 38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return base::Bind(&UsageAndQuotaCallbackDispatcher::DidGetAvailableSpace, 39090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AsWeakPtr()); 39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void DidGetHostUsage(int64 usage) { 39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status_ == kQuotaStatusUnknown) 39690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) status_ = kQuotaStatusOk; 39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.usage = usage; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckCompleted(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void DidGetGlobalLimitedUsage(int64 limited_usage) { 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status_ == kQuotaStatusUnknown) 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) status_ = kQuotaStatusOk; 40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.global_limited_usage = limited_usage; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckCompleted(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void DidGetQuota(QuotaStatusCode status, int64 quota) { 40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status_ == kQuotaStatusUnknown || status_ == kQuotaStatusOk) 41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) status_ = status; 41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.quota = quota; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckCompleted(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidGetAvailableSpace(QuotaStatusCode status, int64 space) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(space, 0); 41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (status_ == kQuotaStatusUnknown || status_ == kQuotaStatusOk) 41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) status_ = status; 41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.available_disk_space = space; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckCompleted(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Run() OVERRIDE { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We initialize waiting_callbacks to 1 so that we won't run 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the completion callback until here even some of the callbacks 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are dispatched synchronously. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckCompleted(); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Aborted() OVERRIDE { 43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_.Run(kQuotaErrorAbort, UsageAndQuota()); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSoon(); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Completed() OVERRIDE { 43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!has_usage_ || usage_and_quota_.usage >= 0); 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!has_global_limited_usage_ || 43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.global_limited_usage >= 0); 43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!has_quota_ || usage_and_quota_.quota >= 0); 44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!has_available_disk_space_ || 44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) usage_and_quota_.available_disk_space >= 0); 44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_.Run(status_, usage_and_quota_); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSoon(); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckCompleted() { 44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (--waiting_callbacks_ <= 0) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallCompleted(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // For sanity checks, they're checked only when DCHECK is on. 45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool has_usage_; 45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool has_global_limited_usage_; 45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool has_quota_; 45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool has_available_disk_space_; 45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) QuotaStatusCode status_; 45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UsageAndQuota usage_and_quota_; 46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) QuotaManager::UsageAndQuotaCallback callback_; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int waiting_callbacks_; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UsageAndQuotaCallbackDispatcher); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuotaManager::GetUsageInfoTask : public QuotaTask { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUsageInfoTask( 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaManager* manager, 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetUsageInfoCallback& callback) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : QuotaTask(manager), 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback), 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Run() OVERRIDE { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_trackers_ = 3; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will populate cached hosts and usage info. 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager()->GetUsageTracker(kStorageTypeTemporary)->GetGlobalUsage( 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetUsageInfoTask::DidGetGlobalUsage, 48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_.GetWeakPtr(), 48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kStorageTypeTemporary)); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager()->GetUsageTracker(kStorageTypePersistent)->GetGlobalUsage( 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetUsageInfoTask::DidGetGlobalUsage, 48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_.GetWeakPtr(), 48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kStorageTypePersistent)); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager()->GetUsageTracker(kStorageTypeSyncable)->GetGlobalUsage( 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetUsageInfoTask::DidGetGlobalUsage, 49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_.GetWeakPtr(), 49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kStorageTypeSyncable)); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Completed() OVERRIDE { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(entries_); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSoon(); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Aborted() OVERRIDE { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(UsageInfoEntries()); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSoon(); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddEntries(StorageType type, UsageTracker* tracker) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, int64> host_usage; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracker->GetCachedHostsUsage(&host_usage); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<std::string, int64>::const_iterator iter = host_usage.begin(); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != host_usage.end(); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iter) { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.push_back(UsageInfo(iter->first, type, iter->second)); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (--remaining_trackers_ == 0) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallCompleted(); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidGetGlobalUsage(StorageType type, int64, int64) { 5181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(manager()->GetUsageTracker(type)); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddEntries(type, manager()->GetUsageTracker(type)); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaManager* manager() const { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<QuotaManager*>(observer()); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUsageInfoCallback callback_; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UsageInfoEntries entries_; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining_trackers_; 5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::WeakPtrFactory<GetUsageInfoTask> weak_factory_; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GetUsageInfoTask); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuotaManager::OriginDataDeleter : public QuotaTask { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OriginDataDeleter(QuotaManager* manager, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int quota_client_mask, 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StatusCallback& callback) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : QuotaTask(manager), 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_(origin), 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(type), 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quota_client_mask_(quota_client_mask), 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_count_(0), 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_clients_(-1), 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skipped_clients_(0), 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback), 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) {} 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Run() OVERRIDE { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_count_ = 0; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_clients_ = manager()->clients_.size(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (QuotaClientList::iterator iter = manager()->clients_.begin(); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != manager()->clients_.end(); ++iter) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quota_client_mask_ & (*iter)->id()) { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*iter)->DeleteOriginData( 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_, type_, 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&OriginDataDeleter::DidDeleteOriginData, 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++skipped_clients_; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (--remaining_clients_ == 0) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallCompleted(); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Completed() OVERRIDE { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_count_ == 0) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only remove the entire origin if we didn't skip any client types. 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skipped_clients_ == 0) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager()->DeleteOriginFromDatabase(origin_, type_); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(kQuotaStatusOk); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(kQuotaErrorInvalidModification); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSoon(); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Aborted() OVERRIDE { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(kQuotaErrorAbort); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSoon(); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidDeleteOriginData(QuotaStatusCode status) { 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(remaining_clients_, 0); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != kQuotaStatusOk) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++error_count_; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (--remaining_clients_ == 0) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallCompleted(); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaManager* manager() const { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<QuotaManager*>(observer()); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL origin_; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type_; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int quota_client_mask_; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_count_; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining_clients_; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int skipped_clients_; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatusCallback callback_; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<OriginDataDeleter> weak_factory_; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OriginDataDeleter); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuotaManager::HostDataDeleter : public QuotaTask { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostDataDeleter(QuotaManager* manager, 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& host, 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int quota_client_mask, 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StatusCallback& callback) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : QuotaTask(manager), 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_(host), 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(type), 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quota_client_mask_(quota_client_mask), 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_count_(0), 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_clients_(-1), 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_deleters_(-1), 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback), 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) {} 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Run() OVERRIDE { 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_count_ = 0; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_clients_ = manager()->clients_.size(); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (QuotaClientList::iterator iter = manager()->clients_.begin(); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != manager()->clients_.end(); ++iter) { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*iter)->GetOriginsForHost( 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_, host_, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&HostDataDeleter::DidGetOriginsForHost, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Completed() OVERRIDE { 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_count_ == 0) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(kQuotaStatusOk); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(kQuotaErrorInvalidModification); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSoon(); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Aborted() OVERRIDE { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(kQuotaErrorAbort); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSoon(); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 65990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void DidGetOriginsForHost(const std::set<GURL>& origins) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(remaining_clients_, 0); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origins_.insert(origins.begin(), origins.end()); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (--remaining_clients_ == 0) { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!origins_.empty()) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleOriginsDeletion(); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallCompleted(); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScheduleOriginsDeletion() { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remaining_deleters_ = origins_.size(); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<GURL>::const_iterator p = origins_.begin(); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p != origins_.end(); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++p) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OriginDataDeleter* deleter = 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new OriginDataDeleter( 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager(), *p, type_, quota_client_mask_, 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&HostDataDeleter::DidDeleteOriginData, 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deleter->Start(); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DidDeleteOriginData(QuotaStatusCode status) { 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(remaining_deleters_, 0); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != kQuotaStatusOk) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++error_count_; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (--remaining_deleters_ == 0) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallCompleted(); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaManager* manager() const { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<QuotaManager*>(observer()); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string host_; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type_; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int quota_client_mask_; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL> origins_; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_count_; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining_clients_; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining_deleters_; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StatusCallback callback_; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<HostDataDeleter> weak_factory_; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(HostDataDeleter); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuotaManager::GetModifiedSinceHelper { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetModifiedSinceOnDBThread(StorageType type, 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time modified_since, 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaDatabase* database) { 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return database->GetOriginsModifiedSince(type, &origins_, modified_since); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void DidGetModifiedSince(const base::WeakPtr<QuotaManager>& manager, 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetOriginsCallback& callback, 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!manager) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The operation was aborted. 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(std::set<GURL>(), type); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->DidDatabaseWork(success); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(origins_, type); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL> origins_; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuotaManager::DumpQuotaTableHelper { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool DumpQuotaTableOnDBThread(QuotaDatabase* database) { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return database->DumpQuotaTable( 7445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&DumpQuotaTableHelper::AppendEntry, base::Unretained(this))); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void DidDumpQuotaTable(const base::WeakPtr<QuotaManager>& manager, 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DumpQuotaTableCallback& callback, 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!manager) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The operation was aborted. 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(QuotaTableEntries()); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->DidDatabaseWork(success); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(entries_); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AppendEntry(const QuotaTableEntry& entry) { 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.push_back(entry); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaTableEntries entries_; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuotaManager::DumpOriginInfoTableHelper { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool DumpOriginInfoTableOnDBThread(QuotaDatabase* database) { 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(database); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return database->DumpOriginInfoTable( 7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&DumpOriginInfoTableHelper::AppendEntry, 7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this))); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void DidDumpOriginInfoTable(const base::WeakPtr<QuotaManager>& manager, 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DumpOriginInfoTableCallback& callback, 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!manager) { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The operation was aborted. 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(OriginInfoTableEntries()); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->DidDatabaseWork(success); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(entries_); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AppendEntry(const OriginInfoTableEntry& entry) { 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.push_back(entry); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OriginInfoTableEntries entries_; 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// QuotaManager --------------------------------------------------------------- 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciQuotaManager::QuotaManager( 8011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool is_incognito, 8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::FilePath& profile_path, 8031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& io_thread, 8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SequencedTaskRunner>& db_thread, 8051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<SpecialStoragePolicy>& special_storage_policy) 8061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : is_incognito_(is_incognito), 8071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile_path_(profile_path), 8081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proxy_(new QuotaManagerProxy(this, io_thread)), 8091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci db_disabled_(false), 8101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci eviction_disabled_(false), 8111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci io_thread_(io_thread), 8121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci db_thread_(db_thread), 8131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci temporary_quota_initialized_(false), 8141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci temporary_quota_override_(-1), 8151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci desired_available_space_(-1), 8161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci special_storage_policy_(special_storage_policy), 8171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci get_disk_space_fn_(&CallSystemGetAmountOfFreeDiskSpace), 8181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci storage_monitor_(new StorageMonitor(this)), 8191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this) { 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetUsageInfo(const GetUsageInfoCallback& callback) { 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUsageInfoTask* get_usage_info = new GetUsageInfoTask(this, callback); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_usage_info->Start(); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuotaManager::GetUsageAndQuotaForWebApps( 829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& origin, 830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StorageType type, 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetUsageAndQuotaCallback& callback) { 83290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (type != kStorageTypeTemporary && 83390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type != kStorageTypePersistent && 83490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type != kStorageTypeSyncable) { 83590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(kQuotaErrorNotSupported, 0, 0); 83690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 83790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 83890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(origin == origin.GetOrigin()); 84090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LazyInitialize(); 84190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 84290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool unlimited = IsStorageUnlimited(origin, type); 84390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool can_query_disk_size = CanQueryDiskSize(origin); 84490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UsageAndQuotaCallbackDispatcher* dispatcher = 84690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new UsageAndQuotaCallbackDispatcher(this); 84790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 84890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UsageAndQuota usage_and_quota; 84990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (unlimited) { 85090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher->set_quota(kNoLimit); 85190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 85290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (type == kStorageTypeTemporary) { 85390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetUsageTracker(type)->GetGlobalLimitedUsage( 85490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher->GetGlobalLimitedUsageCallback()); 85590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetTemporaryGlobalQuota(dispatcher->GetQuotaCallback()); 85690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (type == kStorageTypePersistent) { 85790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetPersistentHostQuota(net::GetHostOrSpecFromURL(origin), 85890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher->GetQuotaCallback()); 85990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 86090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher->set_quota(kSyncableStorageDefaultHostQuota); 86190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 86290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 86390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(GetUsageTracker(type)); 86590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetUsageTracker(type)->GetHostUsage(net::GetHostOrSpecFromURL(origin), 86690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher->GetHostUsageCallback()); 86790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 86890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!is_incognito_ && (unlimited || can_query_disk_size)) 86990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetAvailableSpace(dispatcher->GetAvailableSpaceCallback()); 87090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 87190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher->WaitForResults(base::Bind( 87290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &DispatchUsageAndQuotaForWebApps, 87390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) type, is_incognito_, unlimited, can_query_disk_size, 87490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback)); 875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuotaManager::GetUsageAndQuota( 878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& origin, StorageType type, 879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetUsageAndQuotaCallback& callback) { 880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(origin == origin.GetOrigin()); 881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsStorageUnlimited(origin, type)) { 88390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback.Run(kQuotaStatusOk, 0, kNoLimit); 884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetUsageAndQuotaForWebApps(origin, type, callback); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::NotifyStorageAccessed( 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaClient::ID client_id, 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, StorageType type) { 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(origin == origin.GetOrigin()); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStorageAccessedInternal(client_id, origin, type, base::Time::Now()); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::NotifyStorageModified( 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaClient::ID client_id, 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, StorageType type, int64 delta) { 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(origin == origin.GetOrigin()); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStorageModifiedInternal(client_id, origin, type, delta, 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now()); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::NotifyOriginInUse(const GURL& origin) { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origins_in_use_[origin]++; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::NotifyOriginNoLongerInUse(const GURL& origin) { 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsOriginInUse(origin)); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int& count = origins_in_use_[origin]; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (--count == 0) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origins_in_use_.erase(origin); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuotaManager::SetUsageCacheEnabled(QuotaClient::ID client_id, 919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& origin, 920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StorageType type, 921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool enabled) { 922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LazyInitialize(); 9231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(GetUsageTracker(type)); 924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled); 925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DeleteOriginData( 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, StorageType type, int quota_client_mask, 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StatusCallback& callback) { 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (origin.is_empty() || clients_.empty()) { 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaStatusOk); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(origin == origin.GetOrigin()); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OriginDataDeleter* deleter = 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new OriginDataDeleter(this, origin, type, quota_client_mask, callback); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deleter->Start(); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DeleteHostData(const std::string& host, 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int quota_client_mask, 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const StatusCallback& callback) { 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host.empty() || clients_.empty()) { 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaStatusOk); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostDataDeleter* deleter = 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new HostDataDeleter(this, host, type, quota_client_mask, callback); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deleter->Start(); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetAvailableSpace(const AvailableSpaceCallback& callback) { 96090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!available_space_callbacks_.Add(callback)) 96190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 96290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PostTaskAndReplyWithResult(db_thread_.get(), 964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FROM_HERE, 965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(get_disk_space_fn_, profile_path_), 966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&QuotaManager::DidGetAvailableSpace, 967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) weak_factory_.GetWeakPtr())); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetTemporaryGlobalQuota(const QuotaCallback& callback) { 97190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LazyInitialize(); 97290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!temporary_quota_initialized_) { 97390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) db_initialization_callbacks_.Add(base::Bind( 97490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &QuotaManager::GetTemporaryGlobalQuota, 97590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 97690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 97790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 97890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temporary_quota_override_ > 0) { 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaStatusOk, temporary_quota_override_); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 98390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 98490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UsageAndQuotaCallbackDispatcher* dispatcher = 98590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new UsageAndQuotaCallbackDispatcher(this); 98690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetUsageTracker(kStorageTypeTemporary)-> 98790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetGlobalLimitedUsage(dispatcher->GetGlobalLimitedUsageCallback()); 98890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetAvailableSpace(dispatcher->GetAvailableSpaceCallback()); 98990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher->WaitForResults( 99090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&DispatchTemporaryGlobalQuotaCallback, callback)); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::SetTemporaryGlobalOverrideQuota( 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 new_quota, const QuotaCallback& callback) { 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_quota < 0) { 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback.is_null()) 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaErrorInvalidModification, -1); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_disabled_) { 10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!callback.is_null()) 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaErrorInvalidAccess, -1); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* new_quota_ptr = new int64(new_quota); 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SetTemporaryGlobalOverrideQuotaOnDBThread, 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(new_quota_ptr)), 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidSetTemporaryGlobalOverrideQuota, 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(new_quota_ptr))); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetPersistentHostQuota(const std::string& host, 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuotaCallback& callback) { 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host.empty()) { 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This could happen if we are called on file:///. 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kinuko) We may want to respect --allow-file-access-from-files 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // command line switch. 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaStatusOk, 0); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!persistent_host_quota_callbacks_.Add(host, callback)) 103290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 103390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* quota_ptr = new int64(0); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetPersistentHostQuotaOnDBThread, 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host, 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(quota_ptr)), 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidGetPersistentHostQuota, 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host, 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(quota_ptr))); 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::SetPersistentHostQuota(const std::string& host, 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 new_quota, 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuotaCallback& callback) { 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host.empty()) { 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This could happen if we are called on file:///. 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaErrorNotSupported, 0); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_quota < 0) { 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaErrorInvalidModification, -1); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (kPerHostPersistentQuotaLimit < new_quota) { 10625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Cap the requested size at the per-host quota limit. 10635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new_quota = kPerHostPersistentQuotaLimit; 10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_disabled_) { 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(kQuotaErrorInvalidAccess, -1); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* new_quota_ptr = new int64(new_quota); 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SetPersistentHostQuotaOnDBThread, 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host, 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(new_quota_ptr)), 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidSetPersistentHostQuota, 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host, 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(new_quota_ptr))); 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetGlobalUsage(StorageType type, 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GlobalUsageCallback& callback) { 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 10871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(GetUsageTracker(type)); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUsageTracker(type)->GetGlobalUsage(callback); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetHostUsage(const std::string& host, 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UsageCallback& callback) { 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 10951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(GetUsageTracker(type)); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUsageTracker(type)->GetHostUsage(host, callback); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void QuotaManager::GetHostUsage(const std::string& host, 11004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) StorageType type, 11014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) QuotaClient::ID client_id, 11024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const UsageCallback& callback) { 11034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LazyInitialize(); 11041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(GetUsageTracker(type)); 11054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ClientUsageTracker* tracker = 11064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetUsageTracker(type)->GetClientTracker(client_id); 11074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!tracker) { 11084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback.Run(0); 11094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 11104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 11114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tracker->GetHostUsage(host, callback); 11124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 11134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool QuotaManager::IsTrackingHostUsage(StorageType type, 11154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) QuotaClient::ID client_id) const { 11161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UsageTracker* tracker = GetUsageTracker(type); 11171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return tracker && tracker->GetClientTracker(client_id); 11184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 11194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetStatistics( 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, std::string>* statistics) { 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(statistics); 1123b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (temporary_storage_evictor_) { 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, int64> stats; 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_storage_evictor_->GetStatistics(&stats); 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<std::string, int64>::iterator p = stats.begin(); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p != stats.end(); 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++p) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*statistics)[p->first] = base::Int64ToString(p->second); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuotaManager::IsStorageUnlimited(const GURL& origin, 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type) const { 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For syncable storage we should always enforce quota (since the 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // quota must be capped by the server limit). 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == kStorageTypeSyncable) 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (type == kStorageTypeQuotaNotManaged) 11401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return special_storage_policy_.get() && 11421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) special_storage_policy_->IsStorageUnlimited(origin); 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetOriginsModifiedSince(StorageType type, 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time modified_since, 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetOriginsCallback& callback) { 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetModifiedSinceHelper* helper = new GetModifiedSinceHelper; 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetModifiedSinceHelper::GetModifiedSinceOnDBThread, 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(helper), 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) modified_since), 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetModifiedSinceHelper::DidGetModifiedSince, 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(helper), 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback, 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type)); 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool QuotaManager::ResetUsageTracker(StorageType type) { 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(GetUsageTracker(type)); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetUsageTracker(type)->IsWorking()) 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kStorageTypeTemporary: 1169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) temporary_usage_tracker_.reset(new UsageTracker( 1170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch clients_, kStorageTypeTemporary, special_storage_policy_.get(), 1171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_.get())); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kStorageTypePersistent: 1174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) persistent_usage_tracker_.reset(new UsageTracker( 1175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch clients_, kStorageTypePersistent, special_storage_policy_.get(), 1176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_.get())); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case kStorageTypeSyncable: 1179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) syncable_usage_tracker_.reset(new UsageTracker( 1180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch clients_, kStorageTypeSyncable, special_storage_policy_.get(), 1181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_.get())); 11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid QuotaManager::AddStorageObserver( 1190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver* observer, const StorageObserver::MonitorParams& params) { 1191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(observer); 1192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_->AddObserver(observer, params); 1193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 1194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid QuotaManager::RemoveStorageObserver(StorageObserver* observer) { 1196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(observer); 1197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_->RemoveObserver(observer); 1198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 1199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid QuotaManager::RemoveStorageObserverForFilter( 1201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch StorageObserver* observer, const StorageObserver::Filter& filter) { 1202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(observer); 1203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_->RemoveObserverForFilter(observer, filter); 1204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 1205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuotaManager::~QuotaManager() { 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_->manager_ = NULL; 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::for_each(clients_.begin(), clients_.end(), 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::mem_fun(&QuotaClient::OnQuotaManagerDestroyed)); 1210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (database_) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_thread_->DeleteSoon(FROM_HERE, database_.release()); 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuotaManager::EvictionContext::EvictionContext() 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : evicted_type(kStorageTypeUnknown) { 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuotaManager::EvictionContext::~EvictionContext() { 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::LazyInitialize() { 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 1223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (database_) { 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialization seems to be done already. 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use an empty path to open an in-memory only databse for incognito. 12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) database_.reset(new QuotaDatabase(is_incognito_ ? base::FilePath() : 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_path_.AppendASCII(kDatabaseName))); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) temporary_usage_tracker_.reset(new UsageTracker( 1233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch clients_, kStorageTypeTemporary, special_storage_policy_.get(), 1234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_.get())); 1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) persistent_usage_tracker_.reset(new UsageTracker( 1236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch clients_, kStorageTypePersistent, special_storage_policy_.get(), 1237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_.get())); 1238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) syncable_usage_tracker_.reset(new UsageTracker( 1239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch clients_, kStorageTypeSyncable, special_storage_policy_.get(), 1240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch storage_monitor_.get())); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* temporary_quota_override = new int64(-1); 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* desired_available_space = new int64(-1); 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&InitializeOnDBThread, 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(temporary_quota_override), 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(desired_available_space)), 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidInitialize, 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(temporary_quota_override), 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(desired_available_space))); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::RegisterClient(QuotaClient* client) { 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!database_.get()); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clients_.push_back(client); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UsageTracker* QuotaManager::GetUsageTracker(StorageType type) const { 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kStorageTypeTemporary: 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return temporary_usage_tracker_.get(); 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kStorageTypePersistent: 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return persistent_usage_tracker_.get(); 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kStorageTypeSyncable: 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncable_usage_tracker_.get(); 12681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case kStorageTypeQuotaNotManaged: 12691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 12701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case kStorageTypeUnknown: 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetCachedOrigins( 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, std::set<GURL>* origins) { 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(origins); 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(GetUsageTracker(type)); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUsageTracker(type)->GetCachedOrigins(origins); 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::NotifyStorageAccessedInternal( 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaClient::ID client_id, 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, StorageType type, 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time accessed_time) { 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == kStorageTypeTemporary && !lru_origin_callback_.is_null()) { 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record the accessed origins while GetLRUOrigin task is runing 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to filter out them from eviction. 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) access_notified_origins_.insert(origin); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_disabled_) 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&UpdateAccessTimeOnDBThread, origin, type, accessed_time), 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidDatabaseWork, 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::NotifyStorageModifiedInternal( 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaClient::ID client_id, 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 delta, 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time modified_time) { 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 13111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(GetUsageTracker(type)); 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUsageTracker(type)->UpdateUsageCache(client_id, origin, delta); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&UpdateModifiedTimeOnDBThread, origin, type, modified_time), 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidDatabaseWork, 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DumpQuotaTable(const DumpQuotaTableCallback& callback) { 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DumpQuotaTableHelper* helper = new DumpQuotaTableHelper; 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&DumpQuotaTableHelper::DumpQuotaTableOnDBThread, 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(helper)), 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&DumpQuotaTableHelper::DidDumpQuotaTable, 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(helper), 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback)); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DumpOriginInfoTable( 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DumpOriginInfoTableCallback& callback) { 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DumpOriginInfoTableHelper* helper = new DumpOriginInfoTableHelper; 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&DumpOriginInfoTableHelper::DumpOriginInfoTableOnDBThread, 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(helper)), 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&DumpOriginInfoTableHelper::DidDumpOriginInfoTable, 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(helper), 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback)); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::StartEviction() { 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!temporary_storage_evictor_.get()); 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor( 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, kEvictionIntervalInMilliSeconds)); 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (desired_available_space_ >= 0) 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction( 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_available_space_); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_storage_evictor_->Start(); 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DeleteOriginFromDatabase( 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, StorageType type) { 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_disabled_) 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&DeleteOriginInfoOnDBThread, origin, type), 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidDatabaseWork, 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidOriginDataEvicted(QuotaStatusCode status) { 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only try evict origins that are not in use, so basically 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deletion attempt for eviction should not fail. Let's record 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the origin if we get error and exclude it from future eviction 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the error happens consistently (> kThresholdOfErrorsToBeBlacklisted). 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != kQuotaStatusOk) 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origins_in_error_[eviction_context_.evicted_origin]++; 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eviction_context_.evict_origin_data_callback.Run(status); 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eviction_context_.evict_origin_data_callback.Reset(); 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::ReportHistogram() { 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetGlobalUsage(kStorageTypeTemporary, 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &QuotaManager::DidGetTemporaryGlobalUsageForHistogram, 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetGlobalUsage(kStorageTypePersistent, 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &QuotaManager::DidGetPersistentGlobalUsageForHistogram, 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidGetTemporaryGlobalUsageForHistogram( 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 usage, 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 unlimited_usage) { 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfTemporaryStorage", usage); 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL> origins; 140090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetCachedOrigins(kStorageTypeTemporary, &origins); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_origins = origins.size(); 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t protected_origins = 0; 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t unlimited_origins = 0; 1405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CountOriginType(origins, 1406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) special_storage_policy_.get(), 1407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &protected_origins, 1408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &unlimited_origins); 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Quota.NumberOfTemporaryStorageOrigins", 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_origins); 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Quota.NumberOfProtectedTemporaryStorageOrigins", 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected_origins); 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Quota.NumberOfUnlimitedTemporaryStorageOrigins", 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unlimited_origins); 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidGetPersistentGlobalUsageForHistogram( 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 usage, 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 unlimited_usage) { 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfPersistentStorage", usage); 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL> origins; 142490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetCachedOrigins(kStorageTypePersistent, &origins); 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t num_origins = origins.size(); 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t protected_origins = 0; 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t unlimited_origins = 0; 1429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CountOriginType(origins, 1430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) special_storage_policy_.get(), 1431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &protected_origins, 1432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &unlimited_origins); 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Quota.NumberOfPersistentStorageOrigins", 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_origins); 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Quota.NumberOfProtectedPersistentStorageOrigins", 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected_origins); 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Quota.NumberOfUnlimitedPersistentStorageOrigins", 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unlimited_origins); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetLRUOrigin( 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetLRUOriginCallback& callback) { 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInitialize(); 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This must not be called while there's an in-flight task. 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(lru_origin_callback_.is_null()); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lru_origin_callback_ = callback; 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (db_disabled_) { 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lru_origin_callback_.Run(GURL()); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lru_origin_callback_.Reset(); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL>* exceptions = new std::set<GURL>; 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<GURL, int>::const_iterator p = origins_in_use_.begin(); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p != origins_in_use_.end(); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++p) { 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p->second > 0) 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exceptions->insert(p->first); 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<GURL, int>::const_iterator p = origins_in_error_.begin(); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p != origins_in_error_.end(); 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++p) { 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p->second > QuotaManager::kThresholdOfErrorsToBeBlacklisted) 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exceptions->insert(p->first); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL* url = new GURL; 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetLRUOriginOnDBThread, 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type, 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(exceptions), 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) special_storage_policy_, 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(url)), 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidGetLRUOrigin, 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(url))); 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::EvictOriginData( 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StorageType type, 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EvictOriginDataCallback& callback) { 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(type, kStorageTypeTemporary); 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eviction_context_.evicted_origin = origin; 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eviction_context_.evicted_type = type; 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eviction_context_.evict_origin_data_callback = callback; 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteOriginData(origin, type, QuotaClient::kAllClientsMask, 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidOriginDataEvicted, 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::GetUsageAndQuotaForEviction( 149990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const UsageAndQuotaCallback& callback) { 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(io_thread_->BelongsToCurrentThread()); 150190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LazyInitialize(); 150290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 150390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) UsageAndQuotaCallbackDispatcher* dispatcher = 150490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new UsageAndQuotaCallbackDispatcher(this); 150590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetUsageTracker(kStorageTypeTemporary)-> 150690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetGlobalLimitedUsage(dispatcher->GetGlobalLimitedUsageCallback()); 150790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetTemporaryGlobalQuota(dispatcher->GetQuotaCallback()); 150890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetAvailableSpace(dispatcher->GetAvailableSpaceCallback()); 150990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dispatcher->WaitForResults(callback); 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidSetTemporaryGlobalOverrideQuota( 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuotaCallback& callback, 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int64* new_quota, 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaStatusCode status = kQuotaErrorInvalidAccess; 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidDatabaseWork(success); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) { 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_quota_override_ = *new_quota; 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) status = kQuotaStatusOk; 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (callback.is_null()) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(status, *new_quota); 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void QuotaManager::DidGetPersistentHostQuota(const std::string& host, 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int64* quota, 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidDatabaseWork(success); 153390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) persistent_host_quota_callbacks_.Run( 153490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) host, MakeTuple(kQuotaStatusOk, *quota)); 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidSetPersistentHostQuota(const std::string& host, 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuotaCallback& callback, 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int64* new_quota, 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidDatabaseWork(success); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(success ? kQuotaStatusOk : kQuotaErrorInvalidAccess, *new_quota); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidInitialize(int64* temporary_quota_override, 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64* desired_available_space, 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_quota_override_ = *temporary_quota_override; 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desired_available_space_ = *desired_available_space; 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_quota_initialized_ = true; 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidDatabaseWork(success); 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) histogram_timer_.Start(FROM_HERE, 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds( 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kReportHistogramInterval), 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &QuotaManager::ReportHistogram); 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) db_initialization_callbacks_.Run(MakeTuple()); 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTemporaryGlobalQuota( 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidGetInitialTemporaryGlobalQuota, 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidGetLRUOrigin(const GURL* origin, 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success) { 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidDatabaseWork(success); 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the returned origin is (still) not in the origin_in_use_ set 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and has not been accessed since we posted the task. 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (origins_in_use_.find(*origin) != origins_in_use_.end() || 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) access_notified_origins_.find(*origin) != access_notified_origins_.end()) 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lru_origin_callback_.Run(GURL()); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lru_origin_callback_.Run(*origin); 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) access_notified_origins_.clear(); 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lru_origin_callback_.Reset(); 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidGetInitialTemporaryGlobalQuota( 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuotaStatusCode status, int64 quota_unused) { 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (eviction_disabled_) 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL>* origins = new std::set<GURL>; 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temporary_usage_tracker_->GetCachedOrigins(origins); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will call the StartEviction() when initial origin registration 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is completed. 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyWithResultForDBThread( 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&InitializeTemporaryOriginsInfoOnDBThread, 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Owned(origins)), 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&QuotaManager::DidInitializeTemporaryOriginsInfo, 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidInitializeTemporaryOriginsInfo(bool success) { 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DidDatabaseWork(success); 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartEviction(); 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 160190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void QuotaManager::DidGetAvailableSpace(int64 space) { 160290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) available_space_callbacks_.Run(MakeTuple(kQuotaStatusOk, space)); 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DidDatabaseWork(bool success) { 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_disabled_ = !success; 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::DeleteOnCorrectThread() const { 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!io_thread_->BelongsToCurrentThread() && 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_->DeleteSoon(FROM_HERE, this)) { 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QuotaManager::PostTaskAndReplyWithResultForDBThread( 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<bool(QuotaDatabase*)>& task, 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(bool)>& reply) { 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deleting manager will post another task to DB thread to delete 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |database_|, therefore we can be sure that database_ is alive when this 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // task runs. 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PostTaskAndReplyWithResult( 1625868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_thread_.get(), 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from_here, 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(task, base::Unretained(database_.get())), 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply); 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 163103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace storage 1632