Chromium Code Reviews| Index: content/browser/service_worker/service_worker_cache_storage_manager.cc |
| diff --git a/content/browser/service_worker/service_worker_cache_storage_manager.cc b/content/browser/service_worker/service_worker_cache_storage_manager.cc |
| index cdb6b89ad8b013855692fed9ed1f993c0ecc3bb6..900805f7d8306aa6b74495b827e7d29972c7d785 100644 |
| --- a/content/browser/service_worker/service_worker_cache_storage_manager.cc |
| +++ b/content/browser/service_worker/service_worker_cache_storage_manager.cc |
| @@ -8,15 +8,24 @@ |
| #include <string> |
| #include "base/bind.h" |
| +#include "base/files/file_enumerator.h" |
| +#include "base/files/file_util.h" |
| #include "base/id_map.h" |
| #include "base/sha1.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_util.h" |
| +#include "content/browser/service_worker/service_worker_cache.pb.h" |
| +#include "content/browser/service_worker/service_worker_cache_quota_client.h" |
| #include "content/browser/service_worker/service_worker_cache_storage.h" |
| #include "content/browser/service_worker/service_worker_context_core.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "net/base/net_util.h" |
| +#include "storage/browser/quota/quota_manager_proxy.h" |
| +#include "storage/common/quota/quota_status_code.h" |
| #include "url/gurl.h" |
| +namespace content { |
| + |
| namespace { |
| base::FilePath ConstructOriginPath(const base::FilePath& root_path, |
| @@ -27,37 +36,83 @@ base::FilePath ConstructOriginPath(const base::FilePath& root_path, |
| return root_path.AppendASCII(origin_hash_hex); |
| } |
| -} // namespace |
| +bool DeleteOriginDeleteDir(const base::FilePath& path) { |
|
falken
2014/10/16 04:37:38
I see the point of prefixing the helper function w
jkarlin
2014/10/16 11:28:45
Done.
|
| + return base::DeleteFile(path, true /* recursive */); |
| +} |
| -namespace content { |
| +void DeleteOriginDidDeleteDir( |
| + const storage::QuotaClient::DeletionCallback& callback, |
| + bool rv) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + callback.Run(rv ? storage::kQuotaStatusOk : storage::kQuotaErrorAbort); |
| +} |
| + |
| +std::set<GURL> ListOriginsOnDisk(base::FilePath root_path_) { |
| + std::set<GURL> origins; |
| + base::FileEnumerator file_enum( |
| + root_path_, false /* recursive */, base::FileEnumerator::DIRECTORIES); |
| + |
| + base::FilePath path; |
| + while (!(path = file_enum.Next()).empty()) { |
| + std::string protobuf; |
| + base::ReadFileToString( |
| + path.AppendASCII(ServiceWorkerCacheStorage::kIndexFileName), &protobuf); |
| + |
| + ServiceWorkerCacheStorageIndex index; |
| + if (index.ParseFromString(protobuf)) { |
| + if (index.has_origin()) |
| + origins.insert(GURL(index.origin())); |
| + } |
| + } |
| + |
| + return origins; |
| +} |
| + |
| +void GetOriginsForHostDidListOrigins( |
| + const std::string& host, |
| + const storage::QuotaClient::GetOriginsCallback& callback, |
| + const std::set<GURL>& origins) { |
| + std::set<GURL> out_origins; |
| + for (const GURL& origin : origins) { |
| + if (host == net::GetHostOrSpecFromURL(origin)) |
| + out_origins.insert(origin); |
| + } |
| + callback.Run(out_origins); |
| +} |
| + |
| +} // namespace |
| // static |
| -scoped_ptr<ServiceWorkerCacheStorageManager> |
| +scoped_refptr<ServiceWorkerCacheStorageManager> |
| ServiceWorkerCacheStorageManager::Create( |
| const base::FilePath& path, |
| - const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner) { |
| + const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner, |
| + storage::QuotaManagerProxy* quota_manager_proxy) { |
| base::FilePath root_path = path; |
| if (!path.empty()) { |
| root_path = path.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) |
| .AppendASCII("CacheStorage"); |
| } |
| - return make_scoped_ptr( |
| - new ServiceWorkerCacheStorageManager(root_path, cache_task_runner)); |
| + return make_scoped_refptr(new ServiceWorkerCacheStorageManager( |
| + root_path, cache_task_runner, quota_manager_proxy)); |
| } |
| // static |
| -scoped_ptr<ServiceWorkerCacheStorageManager> |
| +scoped_refptr<ServiceWorkerCacheStorageManager> |
| ServiceWorkerCacheStorageManager::Create( |
| ServiceWorkerCacheStorageManager* old_manager) { |
| - scoped_ptr<ServiceWorkerCacheStorageManager> manager( |
| - new ServiceWorkerCacheStorageManager(old_manager->root_path(), |
| - old_manager->cache_task_runner())); |
| + scoped_refptr<ServiceWorkerCacheStorageManager> manager( |
| + new ServiceWorkerCacheStorageManager( |
| + old_manager->root_path(), |
| + old_manager->cache_task_runner(), |
| + old_manager->quota_manager_proxy_.get())); |
| // These values may be NULL, in which case this will be called again later by |
| // the dispatcher host per usual. |
| manager->SetBlobParametersForCache(old_manager->url_request_context(), |
| old_manager->blob_storage_context()); |
| - return manager.Pass(); |
| + return manager; |
| } |
| ServiceWorkerCacheStorageManager::~ServiceWorkerCacheStorageManager() { |
| @@ -136,12 +191,95 @@ void ServiceWorkerCacheStorageManager::SetBlobParametersForCache( |
| blob_context_ = blob_storage_context; |
| } |
| +void ServiceWorkerCacheStorageManager::GetOriginUsage( |
| + const GURL& origin_url, |
| + const storage::QuotaClient::GetUsageCallback& callback) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + // TODO(jkarlin): Get the actual disk usage for the origin. |
| + callback.Run(0); |
| +} |
| + |
| +void ServiceWorkerCacheStorageManager::GetOrigins( |
| + const storage::QuotaClient::GetOriginsCallback& callback) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + if (MemoryCache()) { |
| + std::set<GURL> origins; |
| + for (const auto& key_value : cache_storage_map_) |
| + origins.insert(key_value.first); |
| + |
| + callback.Run(origins); |
| + return; |
| + } |
| + |
| + PostTaskAndReplyWithResult(cache_task_runner_.get(), |
| + FROM_HERE, |
| + base::Bind(&ListOriginsOnDisk, root_path_), |
| + base::Bind(callback)); |
| +} |
| + |
| +void ServiceWorkerCacheStorageManager::GetOriginsForHost( |
| + const std::string& host, |
| + const storage::QuotaClient::GetOriginsCallback& callback) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + if (MemoryCache()) { |
| + std::set<GURL> origins; |
| + for (const auto& key_value : cache_storage_map_) { |
| + if (host == net::GetHostOrSpecFromURL(key_value.first)) |
| + origins.insert(key_value.first); |
| + } |
| + callback.Run(origins); |
| + return; |
| + } |
| + |
| + PostTaskAndReplyWithResult( |
| + cache_task_runner_.get(), |
| + FROM_HERE, |
| + base::Bind(&ListOriginsOnDisk, root_path_), |
| + base::Bind(&GetOriginsForHostDidListOrigins, host, callback)); |
| +} |
| + |
| +void ServiceWorkerCacheStorageManager::DeleteOriginData( |
| + const GURL& origin, |
| + const storage::QuotaClient::DeletionCallback& callback) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + ServiceWorkerCacheStorage* cache_storage = |
| + FindOrCreateServiceWorkerCacheManager(origin); |
| + cache_storage_map_.erase(origin); |
| + cache_storage->CloseAllCaches(); |
| + |
| + // TODO(jkarlin): Deleting the storage leaves any unfinished operations |
| + // hanging, resulting in unresolved promises. Fix this by guaranteeing that |
| + // callbacks are called in ServiceWorkerStorage. |
| + delete cache_storage; |
| + |
| + if (MemoryCache()) { |
| + callback.Run(storage::kQuotaStatusOk); |
| + return; |
| + } |
| + |
| + PostTaskAndReplyWithResult( |
| + cache_task_runner_.get(), |
| + FROM_HERE, |
| + base::Bind(&DeleteOriginDeleteDir, |
| + ConstructOriginPath(root_path_, origin)), |
| + base::Bind(&DeleteOriginDidDeleteDir, callback)); |
| +} |
| + |
| ServiceWorkerCacheStorageManager::ServiceWorkerCacheStorageManager( |
| const base::FilePath& path, |
| - const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner) |
| + const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner, |
| + storage::QuotaManagerProxy* quota_manager_proxy) |
| : root_path_(path), |
| cache_task_runner_(cache_task_runner), |
| + quota_manager_proxy_(quota_manager_proxy), |
| request_context_(NULL) { |
| + if (quota_manager_proxy_.get()) |
| + quota_manager_proxy_->RegisterClient( |
| + new ServiceWorkerCacheQuotaClient(this)); |
| } |
| ServiceWorkerCacheStorage* |
| @@ -153,13 +291,13 @@ ServiceWorkerCacheStorageManager::FindOrCreateServiceWorkerCacheManager( |
| ServiceWorkerCacheStorageMap::const_iterator it = |
| cache_storage_map_.find(origin); |
| if (it == cache_storage_map_.end()) { |
| - bool memory_only = root_path_.empty(); |
| ServiceWorkerCacheStorage* cache_storage = |
| new ServiceWorkerCacheStorage(ConstructOriginPath(root_path_, origin), |
| - memory_only, |
| + MemoryCache(), |
| cache_task_runner_.get(), |
| request_context_, |
| - blob_context_); |
| + blob_context_, |
| + origin); |
| // The map owns fetch_stores. |
| cache_storage_map_.insert(std::make_pair(origin, cache_storage)); |
| return cache_storage; |