Home | History | Annotate | Download | only in quota
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "webkit/browser/fileapi/quota/quota_backend_impl.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/callback.h"
     11 #include "base/logging.h"
     12 #include "base/sequenced_task_runner.h"
     13 #include "webkit/browser/fileapi/file_system_usage_cache.h"
     14 #include "webkit/browser/quota/quota_client.h"
     15 #include "webkit/browser/quota/quota_manager.h"
     16 #include "webkit/common/fileapi/file_system_util.h"
     17 
     18 namespace fileapi {
     19 
     20 QuotaBackendImpl::QuotaBackendImpl(
     21     base::SequencedTaskRunner* file_task_runner,
     22     ObfuscatedFileUtil* obfuscated_file_util,
     23     FileSystemUsageCache* file_system_usage_cache,
     24     quota::QuotaManagerProxy* quota_manager_proxy)
     25     : file_task_runner_(file_task_runner),
     26       obfuscated_file_util_(obfuscated_file_util),
     27       file_system_usage_cache_(file_system_usage_cache),
     28       quota_manager_proxy_(quota_manager_proxy),
     29       weak_ptr_factory_(this) {
     30 }
     31 
     32 QuotaBackendImpl::~QuotaBackendImpl() {
     33 }
     34 
     35 void QuotaBackendImpl::ReserveQuota(const GURL& origin,
     36                                     FileSystemType type,
     37                                     int64 delta,
     38                                     const ReserveQuotaCallback& callback) {
     39   DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
     40   DCHECK(origin.is_valid());
     41   if (!delta) {
     42     callback.Run(base::PLATFORM_FILE_OK);
     43     return;
     44   }
     45   DCHECK(quota_manager_proxy_);
     46   quota_manager_proxy_->GetUsageAndQuota(
     47       file_task_runner_, origin, FileSystemTypeToQuotaStorageType(type),
     48       base::Bind(&QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota,
     49                  weak_ptr_factory_.GetWeakPtr(),
     50                  QuotaReservationInfo(origin, type, delta), callback));
     51 }
     52 
     53 void QuotaBackendImpl::ReleaseReservedQuota(const GURL& origin,
     54                                             FileSystemType type,
     55                                             int64 size) {
     56   DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
     57   DCHECK(origin.is_valid());
     58   DCHECK_LE(0, size);
     59   if (!size)
     60     return;
     61   ReserveQuotaInternal(QuotaReservationInfo(origin, type, -size));
     62 }
     63 
     64 void QuotaBackendImpl::CommitQuotaUsage(const GURL& origin,
     65                                         FileSystemType type,
     66                                         int64 delta) {
     67   DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
     68   DCHECK(origin.is_valid());
     69   if (!delta)
     70     return;
     71   ReserveQuotaInternal(QuotaReservationInfo(origin, type, delta));
     72   base::FilePath path;
     73   if (GetUsageCachePath(origin, type, &path) != base::PLATFORM_FILE_OK)
     74     return;
     75   bool result = file_system_usage_cache_->AtomicUpdateUsageByDelta(path, delta);
     76   DCHECK(result);
     77 }
     78 
     79 void QuotaBackendImpl::IncrementDirtyCount(const GURL& origin,
     80                                            FileSystemType type) {
     81   DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
     82   DCHECK(origin.is_valid());
     83   base::FilePath path;
     84   if (GetUsageCachePath(origin, type, &path) != base::PLATFORM_FILE_OK)
     85     return;
     86   DCHECK(file_system_usage_cache_);
     87   file_system_usage_cache_->IncrementDirty(path);
     88 }
     89 
     90 void QuotaBackendImpl::DecrementDirtyCount(const GURL& origin,
     91                                            FileSystemType type) {
     92   DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
     93   DCHECK(origin.is_valid());
     94   base::FilePath path;
     95   if (GetUsageCachePath(origin, type, &path) != base::PLATFORM_FILE_OK)
     96     return;
     97   DCHECK(file_system_usage_cache_);
     98   file_system_usage_cache_->DecrementDirty(path);
     99 }
    100 
    101 void QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota(
    102     const QuotaReservationInfo& info,
    103     const ReserveQuotaCallback& callback,
    104     quota::QuotaStatusCode status, int64 usage, int64 quota) {
    105   DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
    106   DCHECK(info.origin.is_valid());
    107   if (status != quota::kQuotaStatusOk) {
    108     callback.Run(base::PLATFORM_FILE_ERROR_FAILED);
    109     return;
    110   }
    111 
    112   if (quota < usage + info.delta) {
    113     callback.Run(base::PLATFORM_FILE_ERROR_NO_SPACE);
    114     return;
    115   }
    116 
    117   ReserveQuotaInternal(info);
    118   if (callback.Run(base::PLATFORM_FILE_OK))
    119     return;
    120   // The requester could not accept the reserved quota. Revert it.
    121   ReserveQuotaInternal(
    122       QuotaReservationInfo(info.origin, info.type, -info.delta));
    123 }
    124 
    125 void QuotaBackendImpl::ReserveQuotaInternal(const QuotaReservationInfo& info) {
    126   DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
    127   DCHECK(info.origin.is_valid());
    128   DCHECK(quota_manager_proxy_);
    129   quota_manager_proxy_->NotifyStorageModified(
    130       quota::QuotaClient::kFileSystem, info.origin,
    131       FileSystemTypeToQuotaStorageType(info.type), info.delta);
    132 }
    133 
    134 base::PlatformFileError QuotaBackendImpl::GetUsageCachePath(
    135     const GURL& origin,
    136     FileSystemType type,
    137     base::FilePath* usage_file_path) {
    138   DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
    139   DCHECK(origin.is_valid());
    140   DCHECK(usage_file_path);
    141   base::PlatformFileError error = base::PLATFORM_FILE_OK;
    142   *usage_file_path =
    143       SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType(
    144           obfuscated_file_util_, origin, type, &error);
    145   return error;
    146 }
    147 
    148 QuotaBackendImpl::QuotaReservationInfo::QuotaReservationInfo(
    149     const GURL& origin, FileSystemType type, int64 delta)
    150     : origin(origin), type(type), delta(delta) {
    151 }
    152 
    153 QuotaBackendImpl::QuotaReservationInfo::~QuotaReservationInfo() {
    154 }
    155 
    156 }  // namespace fileapi
    157