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