browsing_data_quota_helper_impl.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_quota_helper_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browsing_data/browsing_data_helper.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_context.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/storage_partition.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/quota/quota_manager.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserContext;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowsingDataQuotaHelper* BrowsingDataQuotaHelper::Create(Profile* profile) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new BrowsingDataQuotaHelperImpl(
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get(),
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserContext::GetDefaultStoragePartition(profile)->GetQuotaManager());
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::StartFetching(
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FetchResultCallback& callback) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(false, callback.is_null());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(callback_.is_null());
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!is_fetching_);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_ = callback;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quota_info_.clear();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_fetching_ = true;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FetchQuotaInfo();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::RevokeHostQuota(const std::string& host) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!io_thread_->BelongsToCurrentThread()) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->PostTask(
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&BrowsingDataQuotaHelperImpl::RevokeHostQuota, this, host));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quota_manager_->SetPersistentHostQuota(
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host, 0,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&BrowsingDataQuotaHelperImpl::DidRevokeHostQuota,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowsingDataQuotaHelperImpl::BrowsingDataQuotaHelperImpl(
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::MessageLoopProxy* ui_thread,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::MessageLoopProxy* io_thread,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    quota::QuotaManager* quota_manager)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : BrowsingDataQuotaHelper(io_thread),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      quota_manager_(quota_manager),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_fetching_(false),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_thread_(ui_thread),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      io_thread_(io_thread),
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(quota_manager);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowsingDataQuotaHelperImpl::~BrowsingDataQuotaHelperImpl() {}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::FetchQuotaInfo() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!io_thread_->BelongsToCurrentThread()) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->PostTask(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&BrowsingDataQuotaHelperImpl::FetchQuotaInfo, this));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quota_manager_->GetOriginsModifiedSince(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      quota::kStorageTypeTemporary,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Time(),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr()));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::GotOrigins(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::set<GURL>& origins, quota::StorageType type) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::set<GURL>::const_iterator itr = origins.begin();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       itr != origins.end();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++itr)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (BrowsingDataHelper::HasWebScheme(*itr))
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_hosts_.insert(std::make_pair(itr->host(), type));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type == quota::kStorageTypeTemporary ||
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         type == quota::kStorageTypePersistent ||
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         type == quota::kStorageTypeSyncable);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Calling GetOriginsModifiedSince() for all types by chaining callbacks.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == quota::kStorageTypeTemporary) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    quota_manager_->GetOriginsModifiedSince(
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        quota::kStorageTypePersistent,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Time(),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_factory_.GetWeakPtr()));
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else if (type == quota::kStorageTypePersistent) {
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    quota_manager_->GetOriginsModifiedSince(
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        quota::kStorageTypeSyncable,
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Time(),
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&BrowsingDataQuotaHelperImpl::GotOrigins,
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_factory_.GetWeakPtr()));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(type == quota::kStorageTypeSyncable);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessPendingHosts();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::ProcessPendingHosts() {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_hosts_.empty()) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnComplete();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingHosts::iterator itr = pending_hosts_.begin();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string host = itr->first;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quota::StorageType type = itr->second;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_hosts_.erase(itr);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetHostUsage(host, type);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::GetHostUsage(const std::string& host,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               quota::StorageType type) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(quota_manager_.get());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quota_manager_->GetHostUsage(
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host, type,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&BrowsingDataQuotaHelperImpl::GotHostUsage,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 weak_factory_.GetWeakPtr(), host, type));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::GotHostUsage(const std::string& host,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               quota::StorageType type,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               int64 usage) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case quota::kStorageTypeTemporary:
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      quota_info_[host].temporary_usage = usage;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case quota::kStorageTypePersistent:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      quota_info_[host].persistent_usage = usage;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case quota::kStorageTypeSyncable:
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      quota_info_[host].syncable_usage = usage;
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessPendingHosts();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::OnComplete() {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ui_thread_->BelongsToCurrentThread()) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui_thread_->PostTask(
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&BrowsingDataQuotaHelperImpl::OnComplete, this));
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_fetching_ = false;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuotaInfoArray result;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::map<std::string, QuotaInfo>::iterator itr = quota_info_.begin();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       itr != quota_info_.end();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++itr) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuotaInfo* info = &itr->second;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Skip unused entries
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (info->temporary_usage <= 0 &&
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        info->persistent_usage <= 0 &&
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        info->syncable_usage <= 0)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->host = itr->first;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.push_back(*info);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_.Run(result);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_.Reset();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowsingDataQuotaHelperImpl::DidRevokeHostQuota(
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    quota::QuotaStatusCode status_unused,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 quota_unused) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
193