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