// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "webkit/browser/fileapi/quota/quota_backend_impl.h" #include #include "base/bind.h" #include "base/callback.h" #include "base/logging.h" #include "base/sequenced_task_runner.h" #include "webkit/browser/fileapi/file_system_usage_cache.h" #include "webkit/browser/quota/quota_client.h" #include "webkit/browser/quota/quota_manager.h" #include "webkit/common/fileapi/file_system_util.h" namespace fileapi { QuotaBackendImpl::QuotaBackendImpl( base::SequencedTaskRunner* file_task_runner, ObfuscatedFileUtil* obfuscated_file_util, FileSystemUsageCache* file_system_usage_cache, quota::QuotaManagerProxy* quota_manager_proxy) : file_task_runner_(file_task_runner), obfuscated_file_util_(obfuscated_file_util), file_system_usage_cache_(file_system_usage_cache), quota_manager_proxy_(quota_manager_proxy), weak_ptr_factory_(this) { } QuotaBackendImpl::~QuotaBackendImpl() { } void QuotaBackendImpl::ReserveQuota(const GURL& origin, FileSystemType type, int64 delta, const ReserveQuotaCallback& callback) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(origin.is_valid()); if (!delta) { callback.Run(base::PLATFORM_FILE_OK); return; } DCHECK(quota_manager_proxy_); quota_manager_proxy_->GetUsageAndQuota( file_task_runner_, origin, FileSystemTypeToQuotaStorageType(type), base::Bind(&QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota, weak_ptr_factory_.GetWeakPtr(), QuotaReservationInfo(origin, type, delta), callback)); } void QuotaBackendImpl::ReleaseReservedQuota(const GURL& origin, FileSystemType type, int64 size) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(origin.is_valid()); DCHECK_LE(0, size); if (!size) return; ReserveQuotaInternal(QuotaReservationInfo(origin, type, -size)); } void QuotaBackendImpl::CommitQuotaUsage(const GURL& origin, FileSystemType type, int64 delta) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(origin.is_valid()); if (!delta) return; ReserveQuotaInternal(QuotaReservationInfo(origin, type, delta)); base::FilePath path; if (GetUsageCachePath(origin, type, &path) != base::PLATFORM_FILE_OK) return; bool result = file_system_usage_cache_->AtomicUpdateUsageByDelta(path, delta); DCHECK(result); } void QuotaBackendImpl::IncrementDirtyCount(const GURL& origin, FileSystemType type) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(origin.is_valid()); base::FilePath path; if (GetUsageCachePath(origin, type, &path) != base::PLATFORM_FILE_OK) return; DCHECK(file_system_usage_cache_); file_system_usage_cache_->IncrementDirty(path); } void QuotaBackendImpl::DecrementDirtyCount(const GURL& origin, FileSystemType type) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(origin.is_valid()); base::FilePath path; if (GetUsageCachePath(origin, type, &path) != base::PLATFORM_FILE_OK) return; DCHECK(file_system_usage_cache_); file_system_usage_cache_->DecrementDirty(path); } void QuotaBackendImpl::DidGetUsageAndQuotaForReserveQuota( const QuotaReservationInfo& info, const ReserveQuotaCallback& callback, quota::QuotaStatusCode status, int64 usage, int64 quota) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(info.origin.is_valid()); if (status != quota::kQuotaStatusOk) { callback.Run(base::PLATFORM_FILE_ERROR_FAILED); return; } if (quota < usage + info.delta) { callback.Run(base::PLATFORM_FILE_ERROR_NO_SPACE); return; } ReserveQuotaInternal(info); if (callback.Run(base::PLATFORM_FILE_OK)) return; // The requester could not accept the reserved quota. Revert it. ReserveQuotaInternal( QuotaReservationInfo(info.origin, info.type, -info.delta)); } void QuotaBackendImpl::ReserveQuotaInternal(const QuotaReservationInfo& info) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(info.origin.is_valid()); DCHECK(quota_manager_proxy_); quota_manager_proxy_->NotifyStorageModified( quota::QuotaClient::kFileSystem, info.origin, FileSystemTypeToQuotaStorageType(info.type), info.delta); } base::PlatformFileError QuotaBackendImpl::GetUsageCachePath( const GURL& origin, FileSystemType type, base::FilePath* usage_file_path) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); DCHECK(origin.is_valid()); DCHECK(usage_file_path); base::PlatformFileError error = base::PLATFORM_FILE_OK; *usage_file_path = SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType( obfuscated_file_util_, origin, type, &error); return error; } QuotaBackendImpl::QuotaReservationInfo::QuotaReservationInfo( const GURL& origin, FileSystemType type, int64 delta) : origin(origin), type(type), delta(delta) { } QuotaBackendImpl::QuotaReservationInfo::~QuotaReservationInfo() { } } // namespace fileapi