Commit message: None
CVE: None
Vulnerability description: None

Project: Chrome

  bool AddCallback(GetUsageAndQuotaCallback* callback, bool unlimited) {
    if (unlimited)
      unlimited_callbacks_.push_back(callback);
    else
      callbacks_.push_back(callback);
    return (callbacks_.size() + unlimited_callbacks_.size() == 1);
  }

Project: Chrome

  bool AppendEntry(const TableEntry& entry) {
    entries_.push_back(entry);
    return true;
  }

Project: Chrome

  void CallCallbacksAndClear(
      CallbackList* callbacks, QuotaStatusCode status,
      int64 usage, int64 quota) {
    for (CallbackList::iterator iter = callbacks->begin();
         iter != callbacks->end(); ++iter) {
      (*iter)->Run(status, usage, quota);
      delete *iter;
    }
    callbacks->clear();
  }

Project: Chrome

  void CheckCompleted() {
    if (--waiting_callbacks_ <= 0) {
      DispatchCallbacks();
      DCHECK(callbacks_.empty());
      DCHECK(unlimited_callbacks_.empty());

      UsageAndQuotaDispatcherTaskMap& dispatcher_map =
          manager()->usage_and_quota_dispatchers_;
      DCHECK(dispatcher_map.find(std::make_pair(host_, type_)) !=
             dispatcher_map.end());
      dispatcher_map.erase(std::make_pair(host_, type_));
      CallCompleted();
    }
  }

Project: Chrome

void CountOriginType(const std::set<GURL>& origins,
                     SpecialStoragePolicy* policy,
                     size_t* protected_origins,
                     size_t* unlimited_origins) {
  DCHECK(protected_origins);
  DCHECK(unlimited_origins);
  *protected_origins = 0;
  *unlimited_origins = 0;
  if (!policy)
    return;
  for (std::set<GURL>::const_iterator itr = origins.begin();
       itr != origins.end();
       ++itr) {
    if (policy->IsStorageProtected(*itr))
      ++*protected_origins;
    if (policy->IsStorageUnlimited(*itr))
      ++*unlimited_origins;
  }
}

Project: Chrome

QuotaManager::UsageAndQuotaDispatcherTask::Create(
    QuotaManager* manager, const std::string& host, StorageType type) {
  switch (type) {
    case kStorageTypeTemporary:
      return new UsageAndQuotaDispatcherTaskForTemporary(
          manager, host);
    case kStorageTypePersistent:
      return new UsageAndQuotaDispatcherTaskForPersistent(
          manager, host);
    default:
      NOTREACHED();
  }
  return NULL;
}

Project: Chrome

void QuotaManager::DeleteOnCorrectThread() const {
  if (!io_thread_->BelongsToCurrentThread()) {
    io_thread_->DeleteSoon(FROM_HERE, this);
    return;
  }
  delete this;
}

Project: Chrome

void QuotaManager::DeleteOriginData(
    const GURL& origin, StorageType type, StatusCallback* callback) {
  LazyInitialize();

  if (origin.is_empty() || clients_.empty()) {
    callback->Run(kQuotaStatusOk);
    delete callback;
    return;
  }

  OriginDataDeleter* deleter =
      new OriginDataDeleter(this, origin, type, callback);
  deleter->Start();
}

Project: Chrome

  DeleteOriginInfo(
      QuotaManager* manager,
      const GURL& origin,
      StorageType type)
      : DatabaseTaskBase(manager),
        origin_(origin),
        type_(type) {}

Project: Chrome

  void DidDeleteOriginData(QuotaStatusCode status) {
    DCHECK_GT(remaining_clients_, 0);

    if (status != kQuotaStatusOk)
      ++error_count_;

    if (--remaining_clients_ == 0)
      CallCompleted();
  }

Project: Chrome

void QuotaManager::DidGetAvailableSpaceForEviction(
    QuotaStatusCode status,
    int64 available_space) {
  eviction_context_.get_usage_and_quota_callback->Run(status,
      eviction_context_.usage,
      eviction_context_.unlimited_usage,
      eviction_context_.quota, available_space);
  eviction_context_.get_usage_and_quota_callback.reset();
}

Project: Chrome

void QuotaManager::DidGetDatabaseLRUOrigin(const GURL& origin) {
  if (origins_in_use_.find(origin) != origins_in_use_.end() ||
      access_notified_origins_.find(origin) != access_notified_origins_.end())
    lru_origin_callback_->Run(GURL());
  else
    lru_origin_callback_->Run(origin);
  access_notified_origins_.clear();
  lru_origin_callback_.reset();
}

Project: Chrome

  void DidGetGlobalQuota(QuotaStatusCode status,
                         StorageType type,
                         int64 quota) {
    DCHECK_EQ(type_, type);
    quota_status_ = status;
    quota_ = quota;
    CheckCompleted();
  }

Project: Chrome

void QuotaManager::DidGetGlobalQuotaForEviction(
    QuotaStatusCode status,
    StorageType type,
    int64 quota) {
  DCHECK_EQ(type, kStorageTypeTemporary);
  if (status != kQuotaStatusOk) {
    eviction_context_.get_usage_and_quota_callback->Run(
        status, 0, 0, 0, 0);
    eviction_context_.get_usage_and_quota_callback.reset();
    return;
  }

  eviction_context_.quota = quota;
  GetAvailableSpace(callback_factory_.
      NewCallback(&QuotaManager::DidGetAvailableSpaceForEviction));
}

Project: Chrome

  void DidGetGlobalUsage(StorageType type, int64 usage,
                         int64 unlimited_usage) {
    DCHECK_EQ(type_, type);
    DCHECK_GE(usage, unlimited_usage);
    global_usage_ = usage;
    global_unlimited_usage_ = unlimited_usage;
    CheckCompleted();
  }

Project: Chrome

void QuotaManager::DidGetGlobalUsageForEviction(
    StorageType type, int64 usage, int64 unlimited_usage) {
  DCHECK_EQ(type, kStorageTypeTemporary);
  DCHECK_GE(usage, unlimited_usage);
  eviction_context_.usage = usage;
  eviction_context_.unlimited_usage = unlimited_usage;
  GetTemporaryGlobalQuota(callback_factory_.
      NewCallback(&QuotaManager::DidGetGlobalQuotaForEviction));
}

Project: Chrome

  void DidGetHostQuota(QuotaStatusCode status,
                       const std::string& host,
                       StorageType type,
                       int64 quota) {
    DCHECK_EQ(host_, host);
    DCHECK_EQ(type_, type);
    quota_status_ = status;
    quota_ = quota;
    CheckCompleted();
  }

Project: Chrome

  void DidGetHostUsage(const std::string& host,
                       StorageType type,
                       int64 usage) {
    DCHECK_EQ(host_, host);
    DCHECK_EQ(type_, type);
    host_usage_ = usage;
    CheckCompleted();
  }

Project: Chrome

void QuotaManager::DidGetPersistentGlobalUsageForHistogram(
    StorageType type,
    int64 usage,
    int64 unlimited_usage) {
  UMA_HISTOGRAM_MBYTES("Quota.GlobalUsageOfPersistentStorage", usage);

  std::set<GURL> origins;
  GetCachedOrigins(type, &origins);

  size_t num_origins = origins.size();
  size_t protected_origins = 0;
  size_t unlimited_origins = 0;
  CountOriginType(origins, special_storage_policy_,
                  &protected_origins, &unlimited_origins);

  UMA_HISTOGRAM_COUNTS("Quota.NumberOfPersistentStorageOrigins",
                       num_origins);
  UMA_HISTOGRAM_COUNTS("Quota.NumberOfProtectedPersistentStorageOrigins",
                       protected_origins);
  UMA_HISTOGRAM_COUNTS("Quota.NumberOfUnlimitedPersistentStorageOrigins",
                       unlimited_origins);
}

Project: Chrome

void QuotaManager::DidInitializeTemporaryGlobalQuota(int64 quota) {
  temporary_global_quota_ = quota;
  temporary_global_quota_callbacks_.Run(
      db_disabled_ ? kQuotaErrorInvalidAccess : kQuotaStatusOk,
      kStorageTypeTemporary, quota);

  if (db_disabled_ || eviction_disabled_)
    return;

  if (!need_initialize_origins_) {
    StartEviction();
    return;
  }

  temporary_usage_tracker_->GetGlobalUsage(callback_factory_.NewCallback(
      &QuotaManager::DidRunInitialGetTemporaryGlobalUsage));
}

Project: Chrome

void QuotaManager::DidRunInitialGetTemporaryGlobalUsage(
    StorageType type, int64 usage_unused, int64 unlimited_usage_unused) {
  DCHECK_EQ(type, kStorageTypeTemporary);
  scoped_refptr<InitializeTemporaryOriginsInfoTask> task(
      new InitializeTemporaryOriginsInfoTask(
          this, temporary_usage_tracker_.get()));
  task->Start();
}

Project: Chrome

void QuotaManager::DumpOriginInfoTable(
    DumpOriginInfoTableCallback* callback) {
  make_scoped_refptr(new DumpOriginInfoTableTask(this, callback))->Start();
}

Project: Chrome

  DumpOriginInfoTableTask(
      QuotaManager* manager,
      Callback* callback)
      : DatabaseTaskBase(manager),
        callback_(callback) {
  }

Project: Chrome

void QuotaManager::DumpQuotaTable(DumpQuotaTableCallback* callback) {
  make_scoped_refptr(new DumpQuotaTableTask(this, callback))->Start();
}

Project: Chrome

  DumpQuotaTableTask(
      QuotaManager* manager,
      Callback* callback)
      : DatabaseTaskBase(manager),
        callback_(callback) {
  }

Project: Chrome

void QuotaManager::EvictOriginData(
    const GURL& origin,
    StorageType type,
    EvictOriginDataCallback* callback) {
  DCHECK(io_thread_->BelongsToCurrentThread());
  DCHECK_EQ(type, kStorageTypeTemporary);

  eviction_context_.evicted_origin = origin;
  eviction_context_.evicted_type = type;
  eviction_context_.evict_origin_data_callback.reset(callback);

  DeleteOriginData(origin, type, callback_factory_.NewCallback(
      &QuotaManager::DidOriginDataEvicted));
}

Project: Chrome

void QuotaManager::GetAvailableSpace(AvailableSpaceCallback* callback) {
  scoped_refptr<AvailableSpaceQueryTask> task(
      new AvailableSpaceQueryTask(this, db_thread_, profile_path_, callback));
  task->Start();
}

Project: Chrome

void QuotaManager::GetCachedOrigins(
    StorageType type, std::set<GURL>* origins) {
  DCHECK(origins);
  LazyInitialize();
  switch (type) {
    case kStorageTypeTemporary:
      DCHECK(temporary_usage_tracker_.get());
      temporary_usage_tracker_->GetCachedOrigins(origins);
      return;
    case kStorageTypePersistent:
      DCHECK(persistent_usage_tracker_.get());
      persistent_usage_tracker_->GetCachedOrigins(origins);
      return;
    default:
      NOTREACHED();
  }
}

Project: Chrome

void QuotaManager::GetGlobalUsage(
    StorageType type,
    GlobalUsageCallback* callback) {
  LazyInitialize();
  GetUsageTracker(type)->GetGlobalUsage(callback);
}

Project: Chrome

void QuotaManager::GetHostUsage(const std::string& host, StorageType type,
                                HostUsageCallback* callback) {
  LazyInitialize();
  GetUsageTracker(type)->GetHostUsage(host, callback);
}

Project: Chrome

int64 GetInitialTemporaryStorageQuotaSize(const FilePath& path,
                                          bool is_incognito) {
  int64 free_space = base::SysInfo::AmountOfFreeDiskSpace(path);
  UMA_HISTOGRAM_MBYTES("Quota.FreeDiskSpaceForProfile", free_space);

  if (free_space < QuotaManager::kTemporaryStorageQuotaDefaultSize * 2)
    return 0;

  if (is_incognito)
    return QuotaManager::kIncognitoDefaultTemporaryQuota;

  if (free_space < QuotaManager::kTemporaryStorageQuotaDefaultSize * 20)
    return QuotaManager::kTemporaryStorageQuotaDefaultSize;

  if (free_space < QuotaManager::kTemporaryStorageQuotaMaxSize * 20)
    return free_space / 20;

  return QuotaManager::kTemporaryStorageQuotaMaxSize;
}

Project: Chrome

void QuotaManager::GetLRUOrigin(
    StorageType type,
    GetLRUOriginCallback* callback) {
  LazyInitialize();
  DCHECK(!lru_origin_callback_.get());
  lru_origin_callback_.reset(callback);
  if (db_disabled_) {
    lru_origin_callback_->Run(GURL());
    lru_origin_callback_.reset();
    return;
  }
  scoped_refptr<GetLRUOriginTask> task(new GetLRUOriginTask(
      this, type, origins_in_use_,
      origins_in_error_, callback_factory_.NewCallback(
          &QuotaManager::DidGetDatabaseLRUOrigin)));
  task->Start();
}

Project: Chrome

  GetLRUOriginTask(
      QuotaManager* manager,
      StorageType type,
      const std::map<GURL, int>& origins_in_use,
      const std::map<GURL, int>& origins_in_error,
      GetLRUOriginCallback *callback)
      : DatabaseTaskBase(manager),
        type_(type),
        callback_(callback),
        special_storage_policy_(manager->special_storage_policy_) {
    for (std::map<GURL, int>::const_iterator p = origins_in_use.begin();
         p != origins_in_use.end();
         ++p) {
      if (p->second > 0)
        exceptions_.insert(p->first);
    }
    for (std::map<GURL, int>::const_iterator p = origins_in_error.begin();
         p != origins_in_error.end();
         ++p) {
      if (p->second > QuotaManager::kThresholdOfErrorsToBeBlacklisted)
        exceptions_.insert(p->first);
    }
  }

Project: Chrome

  GetModifiedSinceTask(
      QuotaManager* manager,
      StorageType type,
      base::Time modified_since,
      GetOriginsCallback* callback)
      : DatabaseTaskBase(manager),
        type_(type),
        modified_since_(modified_since),
        callback_(callback) {}

Project: Chrome

void QuotaManager::GetOriginsModifiedSince(
    StorageType type,
    base::Time modified_since,
    GetOriginsCallback* callback) {
  LazyInitialize();
  make_scoped_refptr(new GetModifiedSinceTask(
      this, type, modified_since, callback))->Start();
}

Project: Chrome

  GetPersistentHostQuotaTask(
      QuotaManager* manager,
      const std::string& host,
      HostQuotaCallback* callback)
      : DatabaseTaskBase(manager),
        host_(host),
        quota_(-1),
        callback_(callback) {
  }

Project: Chrome

void QuotaManager::GetStatistics(
    std::map<std::string, std::string>* statistics) {
  DCHECK(statistics);
  if (temporary_storage_evictor_.get()) {
    std::map<std::string, int64> stats;
    temporary_storage_evictor_->GetStatistics(&stats);
    for (std::map<std::string, int64>::iterator p = stats.begin();
         p != stats.end();
         ++p)
      (*statistics)[p->first] = base::Int64ToString(p->second);
  }
}

Project: Chrome

void QuotaManager::GetTemporaryGlobalQuota(QuotaCallback* callback) {
  LazyInitialize();
  if (temporary_global_quota_ >= 0) {
    callback->Run(kQuotaStatusOk,
                  kStorageTypeTemporary, temporary_global_quota_);
    delete callback;
    return;
  }
  temporary_global_quota_callbacks_.Add(callback);
}

Project: Chrome

 void QuotaManager::GetUsageAndQuota(
     const GURL& origin, StorageType type,
     GetUsageAndQuotaCallback* callback_ptr) {
  scoped_ptr<GetUsageAndQuotaCallback> callback(callback_ptr);
  LazyInitialize();

  if (type == kStorageTypeUnknown) {
    callback->Run(kQuotaErrorNotSupported, 0, 0);
    return;
  }

  std::string host = net::GetHostOrSpecFromURL(origin);
  UsageAndQuotaDispatcherTaskMap::iterator found =
      usage_and_quota_dispatchers_.find(std::make_pair(host, type));
  if (found == usage_and_quota_dispatchers_.end()) {
    UsageAndQuotaDispatcherTask* dispatcher =
        UsageAndQuotaDispatcherTask::Create(this, host, type);
    found = usage_and_quota_dispatchers_.insert(
        std::make_pair(std::make_pair(host, type), dispatcher)).first;
  }
  if (found->second->AddCallback(
          callback.release(), IsStorageUnlimited(origin))) {
    found->second->Start();
  }
}

Project: Chrome

void QuotaManager::GetUsageAndQuotaForEviction(
    GetUsageAndQuotaForEvictionCallback* callback) {
  DCHECK(io_thread_->BelongsToCurrentThread());
  DCHECK(!eviction_context_.get_usage_and_quota_callback.get());

  eviction_context_.get_usage_and_quota_callback.reset(callback);
  GetGlobalUsage(kStorageTypeTemporary, callback_factory_.
      NewCallback(&QuotaManager::DidGetGlobalUsageForEviction));
}

Project: Chrome

UsageTracker* QuotaManager::GetUsageTracker(StorageType type) const {
  switch (type) {
    case kStorageTypeTemporary:
      return temporary_usage_tracker_.get();
    case kStorageTypePersistent:
      return persistent_usage_tracker_.get();
    default:
      NOTREACHED();
  }
  return NULL;
}

Project: Chrome

  InitializeTask(
      QuotaManager* manager,
      const FilePath& profile_path,
      bool is_incognito)
      : DatabaseTaskBase(manager),
        profile_path_(profile_path),
        is_incognito_(is_incognito),
        need_initialize_origins_(false),
        temporary_storage_quota_(-1) {
  }

Project: Chrome

  InitializeTemporaryOriginsInfoTask(
      QuotaManager* manager,
      UsageTracker* temporary_usage_tracker)
      : DatabaseTaskBase(manager),
        has_registered_origins_(false) {
    DCHECK(temporary_usage_tracker);
    temporary_usage_tracker->GetCachedOrigins(&origins_);
  }

Project: Chrome

void QuotaManager::LazyInitialize() {
  DCHECK(io_thread_->BelongsToCurrentThread());
  if (database_.get()) {
    return;
  }

  database_.reset(new QuotaDatabase(is_incognito_ ? FilePath() :
      profile_path_.AppendASCII(kDatabaseName)));

  temporary_usage_tracker_.reset(
      new UsageTracker(clients_, kStorageTypeTemporary,
                       special_storage_policy_));
  persistent_usage_tracker_.reset(
      new UsageTracker(clients_, kStorageTypePersistent,
                       special_storage_policy_));

  scoped_refptr<InitializeTask> task(
      new InitializeTask(this, profile_path_, is_incognito_));
  task->Start();
}

Project: Chrome

  QuotaCallback* NewWaitableGlobalQuotaCallback() {
    ++waiting_callbacks_;
    return callback_factory_.NewCallback(
            &UsageAndQuotaDispatcherTask::DidGetGlobalQuota);
  }

Project: Chrome

  GlobalUsageCallback* NewWaitableGlobalUsageCallback() {
    ++waiting_callbacks_;
    return callback_factory_.NewCallback(
            &UsageAndQuotaDispatcherTask::DidGetGlobalUsage);
  }

Project: Chrome

  HostQuotaCallback* NewWaitableHostQuotaCallback() {
    ++waiting_callbacks_;
    return callback_factory_.NewCallback(
            &UsageAndQuotaDispatcherTask::DidGetHostQuota);
  }

Project: Chrome

  HostUsageCallback* NewWaitableHostUsageCallback() {
    ++waiting_callbacks_;
    return callback_factory_.NewCallback(
            &UsageAndQuotaDispatcherTask::DidGetHostUsage);
  }

Project: Chrome

void QuotaManager::NotifyOriginInUse(const GURL& origin) {
  DCHECK(io_thread_->BelongsToCurrentThread());
  origins_in_use_[origin]++;
}

Project: Chrome

void QuotaManagerProxy::NotifyOriginInUse(
    const GURL& origin) {
  if (!io_thread_->BelongsToCurrentThread()) {
    io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &QuotaManagerProxy::NotifyOriginInUse, origin));
    return;
  }
  if (manager_)
    manager_->NotifyOriginInUse(origin);
}

Project: Chrome

void QuotaManager::NotifyOriginNoLongerInUse(const GURL& origin) {
  DCHECK(io_thread_->BelongsToCurrentThread());
  DCHECK(IsOriginInUse(origin));
  int& count = origins_in_use_[origin];
  if (--count == 0)
    origins_in_use_.erase(origin);
}

Project: Chrome

void QuotaManagerProxy::NotifyOriginNoLongerInUse(
    const GURL& origin) {
  if (!io_thread_->BelongsToCurrentThread()) {
    io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &QuotaManagerProxy::NotifyOriginNoLongerInUse, origin));
    return;
  }
  if (manager_)
    manager_->NotifyOriginNoLongerInUse(origin);
}

Project: Chrome

void QuotaManager::NotifyStorageAccessed(
    QuotaClient::ID client_id,
    const GURL& origin, StorageType type) {
  NotifyStorageAccessedInternal(client_id, origin, type, base::Time::Now());
}

Project: Chrome

void QuotaManagerProxy::NotifyStorageAccessed(
    QuotaClient::ID client_id,
    const GURL& origin,
    StorageType type) {
  if (!io_thread_->BelongsToCurrentThread()) {
    io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &QuotaManagerProxy::NotifyStorageAccessed,
        client_id, origin, type));
    return;
  }
  if (manager_)
    manager_->NotifyStorageAccessed(client_id, origin, type);
}

Project: Chrome

void QuotaManager::NotifyStorageAccessedInternal(
    QuotaClient::ID client_id,
    const GURL& origin, StorageType type,
    base::Time accessed_time) {
  LazyInitialize();
  if (type == kStorageTypeTemporary && lru_origin_callback_.get()) {
    access_notified_origins_.insert(origin);
  }

  if (db_disabled_)
    return;
  make_scoped_refptr(new UpdateAccessTimeTask(
      this, origin, type, accessed_time))->Start();
}

Project: Chrome

void QuotaManager::NotifyStorageModified(
    QuotaClient::ID client_id,
    const GURL& origin, StorageType type, int64 delta) {
  NotifyStorageModifiedInternal(client_id, origin, type, delta,
                                base::Time::Now());
}

Project: Chrome

void QuotaManagerProxy::NotifyStorageModified(
    QuotaClient::ID client_id,
    const GURL& origin,
    StorageType type,
    int64 delta) {
  if (!io_thread_->BelongsToCurrentThread()) {
    io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &QuotaManagerProxy::NotifyStorageModified,
        client_id, origin, type, delta));
    return;
  }
  if (manager_)
    manager_->NotifyStorageModified(client_id, origin, type, delta);
}

Project: Chrome

void QuotaManager::NotifyStorageModifiedInternal(
    QuotaClient::ID client_id,
    const GURL& origin,
    StorageType type,
    int64 delta,
    base::Time modified_time) {
  LazyInitialize();
  GetUsageTracker(type)->UpdateUsageCache(client_id, origin, delta);
  make_scoped_refptr(new UpdateModifiedTimeTask(
      this, origin, type, modified_time))->Start();
}

Project: Chrome

  OriginDataDeleter(QuotaManager* manager,
                    const GURL& origin,
                    StorageType type,
                    StatusCallback* callback)
      : QuotaTask(manager),
        origin_(origin),
        type_(type),
        error_count_(0),
        remaining_clients_(-1),
        callback_(callback),
        callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}

Project: Chrome

QuotaManager::QuotaManager(bool is_incognito,
                           const FilePath& profile_path,
                           base::MessageLoopProxy* io_thread,
                           base::MessageLoopProxy* db_thread,
                           SpecialStoragePolicy* special_storage_policy)
  : is_incognito_(is_incognito),
    profile_path_(profile_path),
    proxy_(new QuotaManagerProxy(
        ALLOW_THIS_IN_INITIALIZER_LIST(this), io_thread)),
    db_disabled_(false),
    eviction_disabled_(false),
    io_thread_(io_thread),
    db_thread_(db_thread),
    need_initialize_origins_(false),
    temporary_global_quota_(-1),
    special_storage_policy_(special_storage_policy),
    callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
}

Project: Chrome

QuotaManagerProxy::QuotaManagerProxy(
    QuotaManager* manager, base::MessageLoopProxy* io_thread)
    : manager_(manager), io_thread_(io_thread) {
}

Project: Chrome

void QuotaManager::RegisterClient(QuotaClient* client) {
  DCHECK(io_thread_->BelongsToCurrentThread());
  DCHECK(!database_.get());
  clients_.push_back(client);
}

Project: Chrome

void QuotaManagerProxy::RegisterClient(QuotaClient* client) {
  if (!io_thread_->BelongsToCurrentThread()) {
    io_thread_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &QuotaManagerProxy::RegisterClient, client));
    return;
  }
  if (manager_)
    manager_->RegisterClient(client);
  else
    client->OnQuotaManagerDestroyed();
}

Project: Chrome

void QuotaManager::SetPersistentHostQuota(const std::string& host,
                                          int64 new_quota,
                                          HostQuotaCallback* callback_ptr) {
  scoped_ptr<HostQuotaCallback> callback(callback_ptr);
  LazyInitialize();
  if (host.empty()) {
    callback->Run(kQuotaErrorNotSupported, host, kStorageTypePersistent, 0);
    return;
  }
  if (new_quota < 0) {
    callback->Run(kQuotaErrorInvalidModification,
                  host, kStorageTypePersistent, -1);
    return;
  }

  if (!db_disabled_) {
    scoped_refptr<UpdatePersistentHostQuotaTask> task(
        new UpdatePersistentHostQuotaTask(
            this, host, new_quota, callback.release()));
    task->Start();
  } else {
    callback->Run(kQuotaErrorInvalidAccess,
                  host, kStorageTypePersistent, -1);
  }
}

Project: Chrome

void QuotaManager::SetTemporaryGlobalQuota(int64 new_quota,
                                           QuotaCallback* callback) {
  LazyInitialize();
  if (new_quota < 0) {
    callback->Run(kQuotaErrorInvalidModification,
                  kStorageTypeTemporary, -1);
    delete callback;
    return;
  }

  if (!db_disabled_) {
    scoped_refptr<UpdateTemporaryGlobalQuotaTask> task(
        new UpdateTemporaryGlobalQuotaTask(this, new_quota, callback));
    task->Start();
  } else {
    callback->Run(kQuotaErrorInvalidAccess,
                  kStorageTypeTemporary, -1);
    delete callback;
  }
}

Project: Chrome

void QuotaManager::StartEviction() {
  DCHECK(!temporary_storage_evictor_.get());
  temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor(this,
      kEvictionIntervalInMilliSeconds));
  temporary_storage_evictor_->Start();
}

Project: Chrome

  UpdateAccessTimeTask(
      QuotaManager* manager,
      const GURL& origin,
      StorageType type,
      base::Time accessed_time)
      : DatabaseTaskBase(manager),
        origin_(origin),
        type_(type),
        accessed_time_(accessed_time) {}

Project: Chrome

  UpdateModifiedTimeTask(
      QuotaManager* manager,
      const GURL& origin,
      StorageType type,
      base::Time modified_time)
      : DatabaseTaskBase(manager),
        origin_(origin),
        type_(type),
        modified_time_(modified_time) {}

Project: Chrome

  UpdatePersistentHostQuotaTask(
      QuotaManager* manager,
      const std::string& host,
      int new_quota,
      HostQuotaCallback* callback)
      : DatabaseTaskBase(manager),
        host_(host),
        new_quota_(new_quota),
        callback_(callback) {
    DCHECK_GE(new_quota_, 0);
  }

Project: Chrome

  UsageAndQuotaDispatcherTask(
      QuotaManager* manager,
      const std::string& host,
      StorageType type)
      : QuotaTask(manager),
        host_(host),
        type_(type),
        quota_(-1),
        global_usage_(-1),
        global_unlimited_usage_(-1),
        host_usage_(-1),
        quota_status_(kQuotaStatusUnknown),
        waiting_callbacks_(1),
        callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {}

Project: Chrome

  UsageAndQuotaDispatcherTaskForPersistent(
      QuotaManager* manager, const std::string& host)
      : UsageAndQuotaDispatcherTask(manager, host, kStorageTypePersistent) {}

Project: Chrome

  UsageAndQuotaDispatcherTaskForTemporary(
      QuotaManager* manager, const std::string& host)
      : UsageAndQuotaDispatcherTask(manager, host, kStorageTypeTemporary) {}

Project: Chrome

  CallbackList& callbacks() { return callbacks_; }

Project: Chrome

  QuotaDatabase* database() const { return database_; }

Project: Chrome

  bool db_disabled() const { return db_disabled_; }

Project: Chrome

  int64 global_unlimited_usage() const { return global_unlimited_usage_; }

Project: Chrome

  int64 global_usage() const { return global_usage_; }

Project: Chrome

  std::string host() const { return host_; }

Project: Chrome

  int64 host_usage() const { return host_usage_; }

Project: Chrome

  QuotaManager* manager() const {
    return static_cast<QuotaManager*>(observer());
  }

Project: Chrome

  QuotaManager* manager() const { return manager_; }

Project: Chrome

  int64 quota() const { return quota_; }

Project: Chrome

QuotaManager* QuotaManagerProxy::quota_manager() const {
  DCHECK(!io_thread_ || io_thread_->BelongsToCurrentThread());
  return manager_;
}

Project: Chrome

  QuotaStatusCode quota_status() const { return quota_status_; }

Project: Chrome

  void set_db_disabled(bool db_disabled) {
    db_disabled_ = db_disabled;
  }

Project: Chrome

  StorageType type() const { return type_; }

Project: Chrome

  virtual ~AvailableSpaceQueryTask() {}

Project: Chrome

QuotaManager::~QuotaManager() {
  DCHECK(io_thread_->BelongsToCurrentThread());
  proxy_->manager_ = NULL;
  std::for_each(clients_.begin(), clients_.end(),
                std::mem_fun(&QuotaClient::OnQuotaManagerDestroyed));
  if (database_.get())
     db_thread_->DeleteSoon(FROM_HERE, database_.release());
 }

Project: Chrome

QuotaManagerProxy::~QuotaManagerProxy() {
}

Project: Chrome

  virtual ~UsageAndQuotaDispatcherTask() {
    STLDeleteContainerPointers(callbacks_.begin(), callbacks_.end());
    STLDeleteContainerPointers(unlimited_callbacks_.begin(),
                               unlimited_callbacks_.end());
  }

Project: Chrome

  MockStorageClient* CreateClient(
      const MockOriginData* mock_data, size_t mock_data_size) {
    return new MockStorageClient(quota_manager_->proxy(),
                                 mock_data, mock_data_size);
  }

Project: Chrome

  void DeleteClientOriginData(QuotaClient* client,
                        const GURL& origin,
                        StorageType type) {
    DCHECK(client);
    quota_status_ = kQuotaStatusUnknown;
    client->DeleteOriginData(origin, type,
        callback_factory_.NewCallback(
            &QuotaManagerTest::StatusCallback));
  }

Project: Chrome

  void DeleteOriginData(const GURL& origin,
                        StorageType type) {
    quota_status_ = kQuotaStatusUnknown;
    quota_manager_->DeleteOriginData(origin, type,
        callback_factory_.NewCallback(
            &QuotaManagerTest::StatusCallback));
  }

Project: Chrome

  void DeleteOriginFromDatabase(const GURL& origin, StorageType type) {
    quota_manager_->DeleteOriginFromDatabase(origin, type);
  }

Project: Chrome

  void DidDumpOriginInfoTable(const OriginInfoTableEntries& entries) {
    origin_info_entries_ = entries;
  }

Project: Chrome

  void DidDumpQuotaTable(const QuotaTableEntries& entries) {
    quota_entries_ = entries;
  }

Project: Chrome

  void DidGetAvailableSpace(QuotaStatusCode status, int64 available_space) {
    quota_status_ = status;
    available_space_ = available_space;
  }

Project: Chrome

  void DidGetGlobalUsage(StorageType type, int64 usage,
                         int64 unlimited_usage) {
    type_ = type;
    usage_ = usage;
    unlimited_usage_ = unlimited_usage;
  }

Project: Chrome

  void DidGetHostQuota(QuotaStatusCode status,
                       const std::string& host,
                       StorageType type,
                       int64 quota) {
    quota_status_ = status;
    host_ = host;
    type_ = type;
    quota_ = quota;
  }

Project: Chrome

  void DidGetHostUsage(const std::string& host,
                       StorageType type,
                       int64 usage) {
    host_ = host;
    type_ = type;
    usage_ = usage;
  }

Project: Chrome

  void DidGetLRUOrigin(const GURL& origin) {
    lru_origin_ = origin;
  }

Project: Chrome

  void DidGetModifiedOrigins(const std::set<GURL>& origins, StorageType type) {
    modified_origins_ = origins;
    modified_origins_type_ = type;
  }

Project: Chrome

  void DidGetQuota(QuotaStatusCode status,
                   StorageType type,
                   int64 quota) {
    quota_status_ = status;
    type_ = type;
    quota_ = quota;
  }

Project: Chrome

   void DidGetUsageAndQuota(QuotaStatusCode status, int64 usage, int64 quota) {
     quota_status_ = status;
     usage_ = usage;
    quota_ = quota;
  }

Project: Chrome

  void DidGetUsageAndQuotaAdditional(
      QuotaStatusCode status, int64 usage, int64 quota) {
    ++additional_callback_count_;
  }

Project: Chrome

  void DidGetUsageAndQuotaForEviction(QuotaStatusCode status,
      int64 usage, int64 unlimited_usage, int64 quota, int64 available_space) {
    quota_status_ = status;
    usage_ = usage;
    unlimited_usage_ = unlimited_usage;
    quota_ = quota;
    available_space_ = available_space;
  }

Project: Chrome

  void DumpOriginInfoTable() {
    origin_info_entries_.clear();
    quota_manager_->DumpOriginInfoTable(
        callback_factory_.NewCallback(
             &QuotaManagerTest::DidDumpOriginInfoTable));
   }

Project: Chrome

  void EvictOriginData(const GURL& origin,
                       StorageType type) {
    quota_status_ = kQuotaStatusUnknown;
    quota_manager_->EvictOriginData(origin, type,
        callback_factory_.NewCallback(
            &QuotaManagerTest::StatusCallback));
  }

Project: Chrome

  void GetAvailableSpace() {
    quota_status_ = kQuotaStatusUnknown;
    available_space_ = -1;
    quota_manager_->GetAvailableSpace(
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetAvailableSpace));
  }

Project: Chrome

  void GetCachedOrigins(StorageType type, std::set<GURL>* origins) {
    ASSERT_TRUE(origins != NULL);
    origins->clear();
    quota_manager_->GetCachedOrigins(type, origins);
  }

Project: Chrome

  void GetGlobalUsage(StorageType type) {
    type_ = kStorageTypeUnknown;
    usage_ = -1;
    unlimited_usage_ = -1;
    quota_manager_->GetGlobalUsage(type,
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetGlobalUsage));
  }

Project: Chrome

  void GetHostUsage(const std::string& host, StorageType type) {
    host_.clear();
    type_ = kStorageTypeUnknown;
    usage_ = -1;
    quota_manager_->GetHostUsage(host, type,
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetHostUsage));
  }

Project: Chrome

  void GetLRUOrigin(StorageType type) {
    lru_origin_ = GURL();
    quota_manager_->GetLRUOrigin(type,
        callback_factory_.NewCallback(&QuotaManagerTest::DidGetLRUOrigin));
  }

Project: Chrome

  void GetOriginsModifiedSince(StorageType type, base::Time modified_since) {
    modified_origins_.clear();
    modified_origins_type_ = kStorageTypeUnknown;
    quota_manager_->GetOriginsModifiedSince(type, modified_since,
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetModifiedOrigins));
  }

Project: Chrome

  void GetTemporaryGlobalQuota() {
    quota_status_ = kQuotaStatusUnknown;
    quota_ = -1;
    quota_manager_->GetTemporaryGlobalQuota(
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetQuota));
  }

Project: Chrome

   void GetUsageAndQuota(const GURL& origin, StorageType type) {
     quota_status_ = kQuotaStatusUnknown;
     usage_ = -1;
    quota_ = -1;
    quota_manager_->GetUsageAndQuota(origin, type,
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetUsageAndQuota));
  }

Project: Chrome

  void GetUsageAndQuotaForEviction() {
    quota_status_ = kQuotaStatusUnknown;
    usage_ = -1;
    unlimited_usage_ = -1;
    quota_ = -1;
    available_space_ = -1;
    quota_manager_->GetUsageAndQuotaForEviction(
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetUsageAndQuotaForEviction));
  }

Project: Chrome

void QuotaManagerTest::GetUsage_WithModifyTestBody(const StorageType type) {
  const MockOriginData data[] = {
    { "http://foo.com/",   type,  10 },
    { "http://foo.com:1/", type,  20 },
  };
  MockStorageClient* client = CreateClient(data, ARRAYSIZE_UNSAFE(data));
  RegisterClient(client);

  GetUsageAndQuota(GURL("http://foo.com/"), type);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(kQuotaStatusOk, status());
  EXPECT_EQ(10 + 20, usage());

  client->ModifyOriginAndNotify(GURL("http://foo.com/"), type, 30);
  client->ModifyOriginAndNotify(GURL("http://foo.com:1/"), type, -5);
  client->AddOriginAndNotify(GURL("https://foo.com/"), type, 1);

  GetUsageAndQuota(GURL("http://foo.com/"), type);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(kQuotaStatusOk, status());
  EXPECT_EQ(10 + 20 + 30 - 5 + 1, usage());
  int foo_usage = usage();

  client->AddOriginAndNotify(GURL("http://bar.com/"), type, 40);
  GetUsageAndQuota(GURL("http://bar.com/"), type);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(kQuotaStatusOk, status());
  EXPECT_EQ(40, usage());

  GetGlobalUsage(type);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(foo_usage + 40, usage());
  EXPECT_EQ(0, unlimited_usage());
}

Project: Chrome

  void NotifyOriginInUse(const GURL& origin) {
    quota_manager_->NotifyOriginInUse(origin);
  }

Project: Chrome

  void NotifyOriginNoLongerInUse(const GURL& origin) {
    quota_manager_->NotifyOriginNoLongerInUse(origin);
  }

Project: Chrome

  void NotifyStorageAccessed(QuotaClient* client,
                             const GURL& origin,
                             StorageType type) {
    DCHECK(client);
    quota_manager_->NotifyStorageAccessedInternal(
        client->id(), origin, type, IncrementMockTime());
  }

Project: Chrome

  QuotaManagerTest()
      : callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
        mock_time_counter_(0) {
  }

Project: Chrome

  void RegisterClient(MockStorageClient* client) {
     quota_manager_->proxy()->RegisterClient(client);
   }

Project: Chrome

  void RunAdditionalUsageAndQuotaTask(const GURL& origin, StorageType type) {
    quota_manager_->GetUsageAndQuota(origin, type,
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetUsageAndQuotaAdditional));
  }

Project: Chrome

  void SetPersistentHostQuota(const std::string& host, int64 new_quota) {
    quota_status_ = kQuotaStatusUnknown;
    host_.clear();
    type_ = kStorageTypeUnknown;
    quota_ = -1;
    quota_manager_->SetPersistentHostQuota(host, new_quota,
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetHostQuota));
  }

Project: Chrome

  void SetTemporaryGlobalQuota(int64 new_quota) {
    quota_status_ = kQuotaStatusUnknown;
    quota_ = -1;
    quota_manager_->SetTemporaryGlobalQuota(new_quota,
        callback_factory_.NewCallback(
            &QuotaManagerTest::DidGetQuota));
  }

Project: Chrome

  void SetUp() {
    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
    mock_special_storage_policy_ = new MockSpecialStoragePolicy;
    quota_manager_ = new QuotaManager(
        false /* is_incognito */,
        data_dir_.path(),
        MessageLoopProxy::current(),
        MessageLoopProxy::current(),
        mock_special_storage_policy_);
    quota_manager_->eviction_disabled_ = true;
    additional_callback_count_ = 0;
  }

Project: Chrome

  void StatusCallback(QuotaStatusCode status) {
    ++status_callback_count_;
    quota_status_ = status;
  }

Project: Chrome

  int additional_callback_count() const { return additional_callback_count_; }

Project: Chrome

  int64 available_space() const { return available_space_; }

Project: Chrome

  const GURL& lru_origin() const { return lru_origin_; }

Project: Chrome

  MockSpecialStoragePolicy* mock_special_storage_policy() const {
    return mock_special_storage_policy_.get();
   }

Project: Chrome

  const std::set<GURL>& modified_origins() const { return modified_origins_; }

Project: Chrome

  StorageType modified_origins_type() const { return modified_origins_type_; }

Project: Chrome

  QuotaManager* quota_manager() const { return quota_manager_.get(); }

Project: Chrome

  void reset_status_callback_count() { status_callback_count_ = 0; }

Project: Chrome

  void set_additional_callback_count(int c) { additional_callback_count_ = c; }

Project: Chrome

  int status_callback_count() const { return status_callback_count_; }

Project: Chrome

  int64 unlimited_usage() const { return unlimited_usage_; }

Project: Chrome

   int64 usage() const { return usage_; }

Project: Chrome

void ClientUsageTracker::AddCachedHost(const std::string& host) {
  cached_hosts_.insert(host);
}

Project: Chrome

void ClientUsageTracker::AddCachedOrigin(
    const GURL& origin, int64 usage) {
  std::string host = net::GetHostOrSpecFromURL(origin);
  UsageMap::iterator iter = cached_usage_[host].
      insert(UsageMap::value_type(origin, 0)).first;
  int64 old_usage = iter->second;
  iter->second = usage;
  int64 delta = usage - old_usage;
  if (delta) {
    global_usage_ += delta;
    if (global_unlimited_usage_is_valid_ && IsStorageUnlimited(origin))
      global_unlimited_usage_ += delta;
  }
  DCHECK_GE(iter->second, 0);
  DCHECK_GE(global_usage_, 0);
}

Project: Chrome

ClientUsageTracker::ClientUsageTracker(
    UsageTracker* tracker, QuotaClient* client, StorageType type,
    SpecialStoragePolicy* special_storage_policy)
    : tracker_(tracker),
      client_(client),
      type_(type),
      global_usage_(0),
      global_unlimited_usage_(0),
      global_usage_retrieved_(false),
      global_unlimited_usage_is_valid_(true),
      global_usage_task_(NULL),
      special_storage_policy_(special_storage_policy) {
  DCHECK(tracker_);
  DCHECK(client_);
  if (special_storage_policy_)
    special_storage_policy_->AddObserver(this);
}

Project: Chrome

void UsageTracker::DidGetClientGlobalUsage(StorageType type,
                                           int64 usage,
                                           int64 unlimited_usage) {
  DCHECK_EQ(type, type_);
  global_usage_.usage += usage;
  global_usage_.unlimited_usage += unlimited_usage;
  if (--global_usage_.pending_clients == 0) {
    if (global_usage_.usage < 0)
      global_usage_.usage = 0;
    if (global_usage_.unlimited_usage > global_usage_.usage)
      global_usage_.unlimited_usage = global_usage_.usage;
    else if (global_usage_.unlimited_usage < 0)
      global_usage_.unlimited_usage = 0;

    global_usage_callbacks_.Run(type, global_usage_.usage,
                                global_usage_.unlimited_usage);
  }
}

Project: Chrome

void UsageTracker::DidGetClientHostUsage(const std::string& host,
                                         StorageType type,
                                         int64 usage) {
  DCHECK_EQ(type, type_);
  TrackingInfo& info = outstanding_host_usage_[host];
  info.usage += usage;
  if (--info.pending_clients == 0) {
    if (info.usage < 0)
      info.usage = 0;
    host_usage_callbacks_.Run(host, host, type, info.usage);
    outstanding_host_usage_.erase(host);
  }
}

Project: Chrome

  void DidGetUsage(int64 usage) {
    DCHECK(original_message_loop()->BelongsToCurrentThread());
    DCHECK(!pending_origins_.empty());
    DCHECK(client_tracker_);

    DCHECK_GE(usage, 0);
    if (usage < 0)
      usage = 0;

    const GURL& origin = pending_origins_.front();
    std::string host = net::GetHostOrSpecFromURL(origin);
    client_tracker_->AddCachedOrigin(origin, usage);

    pending_origins_.pop_front();
    if (pending_origins_.empty() ||
        host != net::GetHostOrSpecFromURL(pending_origins_.front())) {
      client_tracker_->AddCachedHost(host);
    }

    if (pending_origins_.empty()) {
      CallCompleted();
      DeleteSoon();
    }
  }

Project: Chrome

void ClientUsageTracker::GatherGlobalUsageComplete() {
  DCHECK(global_usage_task_ != NULL);
  global_usage_task_ = NULL;
  global_usage_retrieved_ = true;

  DCHECK(global_usage_callback_.HasCallbacks());
  global_usage_callback_.Run(type_, global_usage_,
                             GetCachedGlobalUnlimitedUsage());

  for (HostUsageCallbackMap::iterator iter = host_usage_callbacks_.Begin();
       iter != host_usage_callbacks_.End(); ++iter) {
    iter->second.Run(iter->first, type_, GetCachedHostUsage(iter->first));
  }
  host_usage_callbacks_.Clear();
}

Project: Chrome

void ClientUsageTracker::GatherHostUsageComplete(const std::string& host) {
  DCHECK(host_usage_tasks_.find(host) != host_usage_tasks_.end());
  host_usage_tasks_.erase(host);
   host_usage_callbacks_.Run(host, host, type_, GetCachedHostUsage(host));
 }

Project: Chrome

  GatherHostUsageTask(
      UsageTracker* tracker,
      QuotaClient* client,
      const std::string& host)
      : GatherUsageTaskBase(tracker, client),
        client_(client),
        host_(host),
        callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
    DCHECK(client_);
  }

Project: Chrome

int64 ClientUsageTracker::GetCachedGlobalUnlimitedUsage() {
  if (!global_unlimited_usage_is_valid_) {
    global_unlimited_usage_ = 0;
    for (HostUsageMap::const_iterator host_iter = cached_usage_.begin();
         host_iter != cached_usage_.end(); host_iter++) {
      const UsageMap& origin_map = host_iter->second;
      for (UsageMap::const_iterator origin_iter = origin_map.begin();
           origin_iter != origin_map.end(); origin_iter++) {
        if (IsStorageUnlimited(origin_iter->first))
          global_unlimited_usage_ += origin_iter->second;
      }
    }
    global_unlimited_usage_is_valid_ = true;
  }
  return global_unlimited_usage_;
}

Project: Chrome

 void UsageTracker::GetCachedOrigins(std::set<GURL>* origins) const {
   DCHECK(origins);
   origins->clear();
  for (ClientTrackerMap::const_iterator iter = client_tracker_map_.begin();
       iter != client_tracker_map_.end(); ++iter) {
    iter->second->GetCachedOrigins(origins);
  }
}

Project: Chrome

 void ClientUsageTracker::GetCachedOrigins(std::set<GURL>* origins) const {
   DCHECK(origins);
   for (HostUsageMap::const_iterator host_iter = cached_usage_.begin();
       host_iter != cached_usage_.end(); host_iter++) {
    const UsageMap& origin_map = host_iter->second;
    for (UsageMap::const_iterator origin_iter = origin_map.begin();
         origin_iter != origin_map.end(); origin_iter++) {
      origins->insert(origin_iter->first);
    }
  }
}

Project: Chrome

ClientUsageTracker* UsageTracker::GetClientTracker(QuotaClient::ID client_id) {
  ClientTrackerMap::iterator found = client_tracker_map_.find(client_id);
  if (found != client_tracker_map_.end())
    return found->second;
  return NULL;
}

Project: Chrome

void UsageTracker::GetGlobalUsage(GlobalUsageCallback* callback) {
  if (client_tracker_map_.size() == 0) {
    callback->Run(type_, 0, 0);
    delete callback;
    return;
  }
  if (global_usage_callbacks_.Add(callback)) {
    global_usage_.pending_clients = client_tracker_map_.size();
    global_usage_.usage = 0;
    global_usage_.unlimited_usage = 0;
    for (ClientTrackerMap::iterator iter = client_tracker_map_.begin();
         iter != client_tracker_map_.end();
         ++iter) {
      iter->second->GetGlobalUsage(callback_factory_.NewCallback(
          &UsageTracker::DidGetClientGlobalUsage));
    }
  }
}

Project: Chrome

void ClientUsageTracker::GetGlobalUsage(GlobalUsageCallback* callback) {
  if (global_usage_retrieved_) {
    callback->Run(type_, global_usage_, GetCachedGlobalUnlimitedUsage());
    delete callback;
    return;
  }
  DCHECK(!global_usage_callback_.HasCallbacks());
  global_usage_callback_.Add(callback);
  global_usage_task_ = new GatherGlobalUsageTask(tracker_, client_);
  global_usage_task_->Start();
}

Project: Chrome

void UsageTracker::GetHostUsage(
    const std::string& host, HostUsageCallback* callback) {
  if (client_tracker_map_.size() == 0) {
    callback->Run(host, type_, 0);
    delete callback;
    return;
  }
  if (host_usage_callbacks_.Add(host, callback)) {
    DCHECK(outstanding_host_usage_.find(host) == outstanding_host_usage_.end());
    outstanding_host_usage_[host].pending_clients = client_tracker_map_.size();
    for (ClientTrackerMap::iterator iter = client_tracker_map_.begin();
         iter != client_tracker_map_.end();
         ++iter) {
      iter->second->GetHostUsage(host, callback_factory_.NewCallback(
          &UsageTracker::DidGetClientHostUsage));
    }
  }
}

Project: Chrome

  void GetUsageForOrigins(const std::set<GURL>& origins, StorageType type) {
    DCHECK(original_message_loop()->BelongsToCurrentThread());
    std::vector<GURL> origins_to_gather;
    std::set<GURL> cached_origins;
    client_tracker()->GetCachedOrigins(&cached_origins);
    std::set<GURL> already_added;
    for (std::set<GURL>::const_iterator iter = origins.begin();
         iter != origins.end(); ++iter) {
      if (cached_origins.find(*iter) == cached_origins.end() &&
          already_added.insert(*iter).second) {
        origins_to_gather.push_back(*iter);
      }
    }
    if (origins_to_gather.empty()) {
      CallCompleted();
      DeleteSoon();
      return;
    }

    std::sort(origins_to_gather.begin(), origins_to_gather.end(), SortByHost);

    for (std::vector<GURL>::const_iterator iter = origins_to_gather.begin();
         iter != origins_to_gather.end(); iter++)
      pending_origins_.push_back(*iter);

    for (std::vector<GURL>::const_iterator iter = origins_to_gather.begin();
         iter != origins_to_gather.end(); iter++)
      client_->GetOriginUsage(
          *iter,
          tracker_->type(),
          callback_factory_.NewCallback(&GatherUsageTaskBase::DidGetUsage));
  }

Project: Chrome

bool ClientUsageTracker::IsStorageUnlimited(const GURL& origin) const {
  return special_storage_policy_.get() &&
         special_storage_policy_->IsStorageUnlimited(origin);
}

Project: Chrome

void ClientUsageTracker::NoopHostUsageCallback(
    const std::string& host,  StorageType type, int64 usage) {
}

Project: Chrome

void ClientUsageTracker::OnSpecialStoragePolicyChanged() {
  DCHECK(CalledOnValidThread());
  global_unlimited_usage_is_valid_ = false;
}

Project: Chrome

bool SortByHost(const GURL& lhs, const GURL& rhs) {
  return net::GetHostOrSpecFromURL(lhs) > net::GetHostOrSpecFromURL(rhs);
}

Project: Chrome

void UsageTracker::UpdateUsageCache(
    QuotaClient::ID client_id, const GURL& origin, int64 delta) {
  ClientUsageTracker* client_tracker = GetClientTracker(client_id);
  DCHECK(client_tracker);
   client_tracker->UpdateUsageCache(origin, delta);
 }

Project: Chrome

void ClientUsageTracker::UpdateUsageCache(
    const GURL& origin, int64 delta) {
  std::string host = net::GetHostOrSpecFromURL(origin);
  if (cached_hosts_.find(host) != cached_hosts_.end()) {
    cached_usage_[host][origin] += delta;
    global_usage_ += delta;
    if (global_unlimited_usage_is_valid_ && IsStorageUnlimited(origin))
      global_unlimited_usage_ += delta;
    DCHECK_GE(cached_usage_[host][origin], 0);
    DCHECK_GE(global_usage_, 0);
    return;
  }

  GetHostUsage(host,
                NewCallback(this, &ClientUsageTracker::NoopHostUsageCallback));
 }

Project: Chrome

UsageTracker::UsageTracker(const QuotaClientList& clients, StorageType type,
                           SpecialStoragePolicy* special_storage_policy)
    : type_(type),
      callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
  for (QuotaClientList::const_iterator iter = clients.begin();
      iter != clients.end();
      ++iter) {
    client_tracker_map_.insert(std::make_pair(
        (*iter)->id(),
        new ClientUsageTracker(this, *iter, type, special_storage_policy)));
  }
}

Project: Chrome

  ClientUsageTracker* client_tracker() const { return client_tracker_; }

Project: Chrome

  UsageTracker* tracker() const { return tracker_; }

Project: Chrome

ClientUsageTracker::~ClientUsageTracker() {
  if (special_storage_policy_)
    special_storage_policy_->RemoveObserver(this);
}

Project: Chrome

  virtual ~GatherGlobalUsageTask() {}

Project: Chrome

  virtual ~GatherHostUsageTask() {}

Project: Chrome

  virtual ~GatherUsageTaskBase() {}

Project: Chrome

UsageTracker::~UsageTracker() {
  STLDeleteValues(&client_tracker_map_);
}