| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/service_worker/service_worker_cache_storage.h" | 5 #include "content/browser/service_worker/service_worker_cache_storage.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/files/memory_mapped_file.h" | 10 #include "base/files/memory_mapped_file.h" |
| 11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 12 #include "base/sha1.h" | 12 #include "base/sha1.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "content/browser/service_worker/service_worker_cache.h" | 16 #include "content/browser/service_worker/service_worker_cache.h" |
| 17 #include "content/browser/service_worker/service_worker_cache.pb.h" | 17 #include "content/browser/service_worker/service_worker_cache.pb.h" |
| 18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
| 19 #include "net/base/directory_lister.h" | 19 #include "net/base/directory_lister.h" |
| 20 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
| 21 #include "webkit/browser/blob/blob_storage_context.h" | 21 #include "webkit/browser/blob/blob_storage_context.h" |
| 22 | 22 |
| 23 namespace content { | 23 namespace content { |
| 24 | 24 |
| 25 // static | |
| 26 const int ServiceWorkerCacheStorage::kInvalidCacheID = -1; | |
| 27 | |
| 28 // The meta information related to each ServiceWorkerCache that the | |
| 29 // ServiceWorkerCacheManager needs to keep track of. | |
| 30 // TODO(jkarlin): Add reference counting so that the deletion of javascript | |
| 31 // objects can delete the ServiceWorkerCache. | |
| 32 struct ServiceWorkerCacheStorage::CacheContext { | |
| 33 CacheContext(const std::string& name, | |
| 34 CacheID id, | |
| 35 scoped_ptr<ServiceWorkerCache> cache) | |
| 36 : name(name), id(id), cache(cache.Pass()) {} | |
| 37 std::string name; | |
| 38 CacheID id; | |
| 39 scoped_ptr<ServiceWorkerCache> cache; | |
| 40 }; | |
| 41 | 25 |
| 42 // Handles the loading and clean up of ServiceWorkerCache objects. The | 26 // Handles the loading and clean up of ServiceWorkerCache objects. The |
| 43 // callback of every public method is guaranteed to be called. | 27 // callback of every public method is guaranteed to be called. |
| 44 class ServiceWorkerCacheStorage::CacheLoader { | 28 class ServiceWorkerCacheStorage::CacheLoader { |
| 45 public: | 29 public: |
| 46 typedef base::Callback<void(scoped_ptr<ServiceWorkerCache>)> CacheCallback; | 30 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)> |
| 31 CacheCallback; |
| 47 typedef base::Callback<void(bool)> BoolCallback; | 32 typedef base::Callback<void(bool)> BoolCallback; |
| 48 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> | 33 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> |
| 49 StringsCallback; | 34 StringsCallback; |
| 50 | 35 |
| 51 CacheLoader(base::SequencedTaskRunner* cache_task_runner, | 36 CacheLoader(base::SequencedTaskRunner* cache_task_runner, |
| 52 net::URLRequestContext* request_context, | 37 net::URLRequestContext* request_context, |
| 53 base::WeakPtr<storage::BlobStorageContext> blob_context) | 38 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 54 : cache_task_runner_(cache_task_runner), | 39 : cache_task_runner_(cache_task_runner), |
| 55 request_context_(request_context), | 40 request_context_(request_context), |
| 56 blob_context_(blob_context) {} | 41 blob_context_(blob_context) {} |
| 57 | 42 |
| 58 virtual ~CacheLoader() {} | 43 virtual ~CacheLoader() {} |
| 59 | 44 |
| 60 // Loads the given cache_name, the cache is NULL if it fails. If the cache | 45 // Loads the given cache_name, the cache is NULL if it fails. If the cache |
| 61 // doesn't exist a new one is created. | 46 // doesn't exist a new one is created. |
| 62 virtual scoped_ptr<ServiceWorkerCache> CreateServiceWorkerCache( | 47 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
| 63 const std::string& cache_name) = 0; | 48 const std::string& cache_name) = 0; |
| 64 | 49 |
| 65 // Deletes any pre-existing cache of the same name and then loads it. | 50 // Deletes any pre-existing cache of the same name and then loads it. |
| 66 virtual void CreateCache(const std::string& cache_name, | 51 virtual void CreateCache(const std::string& cache_name, |
| 67 const CacheCallback& callback) = 0; | 52 const CacheCallback& callback) = 0; |
| 68 | 53 |
| 69 // After the backend has been deleted, do any extra house keeping such as | 54 // After the backend has been deleted, do any extra house keeping such as |
| 70 // removing the cache's directory. | 55 // removing the cache's directory. |
| 71 virtual void CleanUpDeletedCache(const std::string& key, | 56 virtual void CleanUpDeletedCache(const std::string& key, |
| 72 const BoolCallback& callback) = 0; | 57 const BoolCallback& callback) = 0; |
| 73 | 58 |
| 74 // Writes the cache names (and sizes) to disk if applicable. | 59 // Writes the cache names (and sizes) to disk if applicable. |
| 75 virtual void WriteIndex(const CacheMap& caches, | 60 virtual void WriteIndex(const CacheMap& caches, |
| 76 const BoolCallback& callback) = 0; | 61 const BoolCallback& callback) = 0; |
| 77 | 62 |
| 78 // Loads the cache names from disk if applicable. | 63 // Loads the cache names from disk if applicable. |
| 79 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 64 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
| 80 const StringsCallback& callback) = 0; | 65 const StringsCallback& callback) = 0; |
| 81 | 66 |
| 82 protected: | 67 protected: |
| 83 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; | 68 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; |
| 84 net::URLRequestContext* request_context_; | 69 net::URLRequestContext* request_context_; |
| 85 base::WeakPtr<storage::BlobStorageContext> blob_context_; | 70 base::WeakPtr<storage::BlobStorageContext> blob_context_; |
| 86 }; | 71 }; |
| 87 | 72 |
| 73 // Creates memory-only ServiceWorkerCaches. Because these caches have no |
| 74 // persistent storage it is not safe to free them from memory if they might be |
| 75 // used again. Therefore this class holds a reference to each cache until the |
| 76 // cache is deleted. |
| 88 class ServiceWorkerCacheStorage::MemoryLoader | 77 class ServiceWorkerCacheStorage::MemoryLoader |
| 89 : public ServiceWorkerCacheStorage::CacheLoader { | 78 : public ServiceWorkerCacheStorage::CacheLoader { |
| 90 public: | 79 public: |
| 91 MemoryLoader(base::SequencedTaskRunner* cache_task_runner, | 80 MemoryLoader(base::SequencedTaskRunner* cache_task_runner, |
| 92 net::URLRequestContext* request_context, | 81 net::URLRequestContext* request_context, |
| 93 base::WeakPtr<storage::BlobStorageContext> blob_context) | 82 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 94 : CacheLoader(cache_task_runner, request_context, blob_context) {} | 83 : CacheLoader(cache_task_runner, request_context, blob_context) {} |
| 95 | 84 |
| 96 virtual scoped_ptr<ServiceWorkerCache> CreateServiceWorkerCache( | 85 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
| 97 const std::string& cache_name) OVERRIDE { | 86 const std::string& cache_name) OVERRIDE { |
| 98 return ServiceWorkerCache::CreateMemoryCache(request_context_, | 87 return ServiceWorkerCache::CreateMemoryCache(request_context_, |
| 99 blob_context_); | 88 blob_context_); |
| 100 } | 89 } |
| 101 | 90 |
| 102 virtual void CreateCache(const std::string& cache_name, | 91 virtual void CreateCache(const std::string& cache_name, |
| 103 const CacheCallback& callback) OVERRIDE { | 92 const CacheCallback& callback) OVERRIDE { |
| 104 callback.Run(CreateServiceWorkerCache(cache_name).Pass()); | 93 scoped_refptr<ServiceWorkerCache> cache = |
| 94 ServiceWorkerCache::CreateMemoryCache(request_context_, blob_context_); |
| 95 cache_refs_.insert(std::make_pair(cache_name, cache)); |
| 96 callback.Run(cache); |
| 105 } | 97 } |
| 106 | 98 |
| 107 virtual void CleanUpDeletedCache(const std::string& cache_name, | 99 virtual void CleanUpDeletedCache(const std::string& cache_name, |
| 108 const BoolCallback& callback) OVERRIDE { | 100 const BoolCallback& callback) OVERRIDE { |
| 101 CacheRefMap::iterator it = cache_refs_.find(cache_name); |
| 102 DCHECK(it != cache_refs_.end()); |
| 103 cache_refs_.erase(it); |
| 109 callback.Run(true); | 104 callback.Run(true); |
| 110 } | 105 } |
| 111 | 106 |
| 112 virtual void WriteIndex(const CacheMap& caches, | 107 virtual void WriteIndex(const CacheMap& caches, |
| 113 const BoolCallback& callback) OVERRIDE { | 108 const BoolCallback& callback) OVERRIDE { |
| 114 callback.Run(false); | 109 callback.Run(false); |
| 115 } | 110 } |
| 116 | 111 |
| 117 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 112 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
| 118 const StringsCallback& callback) OVERRIDE { | 113 const StringsCallback& callback) OVERRIDE { |
| 119 callback.Run(cache_names.Pass()); | 114 callback.Run(cache_names.Pass()); |
| 120 } | 115 } |
| 121 | 116 |
| 122 private: | 117 private: |
| 118 typedef std::map<std::string, scoped_refptr<ServiceWorkerCache> > CacheRefMap; |
| 123 virtual ~MemoryLoader() {} | 119 virtual ~MemoryLoader() {} |
| 120 |
| 121 // Keep a reference to each cache to ensure that it's not freed before the |
| 122 // client calls ServiceWorkerCacheStorage::Delete or the CacheStorage is |
| 123 // freed. |
| 124 CacheRefMap cache_refs_; |
| 124 }; | 125 }; |
| 125 | 126 |
| 126 class ServiceWorkerCacheStorage::SimpleCacheLoader | 127 class ServiceWorkerCacheStorage::SimpleCacheLoader |
| 127 : public ServiceWorkerCacheStorage::CacheLoader { | 128 : public ServiceWorkerCacheStorage::CacheLoader { |
| 128 public: | 129 public: |
| 129 SimpleCacheLoader(const base::FilePath& origin_path, | 130 SimpleCacheLoader(const base::FilePath& origin_path, |
| 130 base::SequencedTaskRunner* cache_task_runner, | 131 base::SequencedTaskRunner* cache_task_runner, |
| 131 net::URLRequestContext* request_context, | 132 net::URLRequestContext* request_context, |
| 132 base::WeakPtr<storage::BlobStorageContext> blob_context) | 133 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 133 : CacheLoader(cache_task_runner, request_context, blob_context), | 134 : CacheLoader(cache_task_runner, request_context, blob_context), |
| 134 origin_path_(origin_path), | 135 origin_path_(origin_path), |
| 135 weak_ptr_factory_(this) {} | 136 weak_ptr_factory_(this) {} |
| 136 | 137 |
| 137 virtual scoped_ptr<ServiceWorkerCache> CreateServiceWorkerCache( | 138 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
| 138 const std::string& cache_name) OVERRIDE { | 139 const std::string& cache_name) OVERRIDE { |
| 139 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 140 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 140 | 141 |
| 141 return ServiceWorkerCache::CreatePersistentCache( | 142 return ServiceWorkerCache::CreatePersistentCache( |
| 142 CreatePersistentCachePath(origin_path_, cache_name), | 143 CreatePersistentCachePath(origin_path_, cache_name), |
| 143 request_context_, | 144 request_context_, |
| 144 blob_context_); | 145 blob_context_); |
| 145 } | 146 } |
| 146 | 147 |
| 147 virtual void CreateCache(const std::string& cache_name, | 148 virtual void CreateCache(const std::string& cache_name, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 169 if (base::PathExists(cache_path)) | 170 if (base::PathExists(cache_path)) |
| 170 base::DeleteFile(cache_path, /* recursive */ true); | 171 base::DeleteFile(cache_path, /* recursive */ true); |
| 171 return base::CreateDirectory(cache_path); | 172 return base::CreateDirectory(cache_path); |
| 172 } | 173 } |
| 173 | 174 |
| 174 static void CreateCachePreppedDir(const std::string& cache_name, | 175 static void CreateCachePreppedDir(const std::string& cache_name, |
| 175 const CacheCallback& callback, | 176 const CacheCallback& callback, |
| 176 base::WeakPtr<SimpleCacheLoader> loader, | 177 base::WeakPtr<SimpleCacheLoader> loader, |
| 177 bool success) { | 178 bool success) { |
| 178 if (!success || !loader) { | 179 if (!success || !loader) { |
| 179 callback.Run(scoped_ptr<ServiceWorkerCache>()); | 180 callback.Run(scoped_refptr<ServiceWorkerCache>()); |
| 180 return; | 181 return; |
| 181 } | 182 } |
| 182 | 183 |
| 183 callback.Run(loader->CreateServiceWorkerCache(cache_name)); | 184 callback.Run(loader->CreateServiceWorkerCache(cache_name)); |
| 184 } | 185 } |
| 185 | 186 |
| 186 virtual void CleanUpDeletedCache(const std::string& cache_name, | 187 virtual void CleanUpDeletedCache(const std::string& cache_name, |
| 187 const BoolCallback& callback) OVERRIDE { | 188 const BoolCallback& callback) OVERRIDE { |
| 188 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 189 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 189 | 190 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 211 const BoolCallback& callback) OVERRIDE { | 212 const BoolCallback& callback) OVERRIDE { |
| 212 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 213 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 213 | 214 |
| 214 // 1. Create the index file as a string. (WriteIndex) | 215 // 1. Create the index file as a string. (WriteIndex) |
| 215 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) | 216 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) |
| 216 | 217 |
| 217 ServiceWorkerCacheStorageIndex index; | 218 ServiceWorkerCacheStorageIndex index; |
| 218 | 219 |
| 219 for (CacheMap::const_iterator it = caches.begin(); it != caches.end(); | 220 for (CacheMap::const_iterator it = caches.begin(); it != caches.end(); |
| 220 ++it) { | 221 ++it) { |
| 221 const CacheContext* cache = it->second; | |
| 222 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); | 222 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); |
| 223 index_cache->set_name(cache->name); | 223 index_cache->set_name(it->first); |
| 224 index_cache->set_size(0); // TODO(jkarlin): Make this real. | 224 index_cache->set_size(0); // TODO(jkarlin): Make this real. |
| 225 } | 225 } |
| 226 | 226 |
| 227 std::string serialized; | 227 std::string serialized; |
| 228 bool success = index.SerializeToString(&serialized); | 228 bool success = index.SerializeToString(&serialized); |
| 229 DCHECK(success); | 229 DCHECK(success); |
| 230 | 230 |
| 231 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); | 231 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); |
| 232 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); | 232 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); |
| 233 | 233 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; | 330 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; |
| 331 }; | 331 }; |
| 332 | 332 |
| 333 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( | 333 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( |
| 334 const base::FilePath& path, | 334 const base::FilePath& path, |
| 335 bool memory_only, | 335 bool memory_only, |
| 336 base::SequencedTaskRunner* cache_task_runner, | 336 base::SequencedTaskRunner* cache_task_runner, |
| 337 net::URLRequestContext* request_context, | 337 net::URLRequestContext* request_context, |
| 338 base::WeakPtr<storage::BlobStorageContext> blob_context) | 338 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 339 : initialized_(false), | 339 : initialized_(false), |
| 340 next_cache_id_(0), | |
| 341 origin_path_(path), | 340 origin_path_(path), |
| 342 cache_task_runner_(cache_task_runner), | 341 cache_task_runner_(cache_task_runner), |
| 342 memory_only_(memory_only), |
| 343 weak_factory_(this) { | 343 weak_factory_(this) { |
| 344 if (memory_only) | 344 if (memory_only) |
| 345 cache_loader_.reset(new MemoryLoader( | 345 cache_loader_.reset(new MemoryLoader( |
| 346 cache_task_runner_.get(), request_context, blob_context)); | 346 cache_task_runner_.get(), request_context, blob_context)); |
| 347 else | 347 else |
| 348 cache_loader_.reset(new SimpleCacheLoader( | 348 cache_loader_.reset(new SimpleCacheLoader( |
| 349 origin_path_, cache_task_runner_.get(), request_context, blob_context)); | 349 origin_path_, cache_task_runner_.get(), request_context, blob_context)); |
| 350 } | 350 } |
| 351 | 351 |
| 352 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { | 352 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { |
| 353 STLDeleteContainerPairSecondPointers(cache_map_.begin(), cache_map_.end()); | |
| 354 } | 353 } |
| 355 | 354 |
| 356 void ServiceWorkerCacheStorage::CreateCache( | 355 void ServiceWorkerCacheStorage::CreateCache( |
| 357 const std::string& cache_name, | 356 const std::string& cache_name, |
| 358 const CacheAndErrorCallback& callback) { | 357 const CacheAndErrorCallback& callback) { |
| 359 if (!initialized_) { | 358 if (!initialized_) { |
| 360 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, | 359 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, |
| 361 weak_factory_.GetWeakPtr(), | 360 weak_factory_.GetWeakPtr(), |
| 362 cache_name, | 361 cache_name, |
| 363 callback)); | 362 callback)); |
| 364 return; | 363 return; |
| 365 } | 364 } |
| 366 | 365 |
| 367 if (GetLoadedCache(cache_name)) { | 366 if (cache_map_.find(cache_name) != cache_map_.end()) { |
| 368 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_EXISTS); | 367 callback.Run(scoped_refptr<ServiceWorkerCache>(), |
| 368 CACHE_STORAGE_ERROR_EXISTS); |
| 369 return; | 369 return; |
| 370 } | 370 } |
| 371 | 371 |
| 372 cache_loader_->CreateCache( | 372 cache_loader_->CreateCache( |
| 373 cache_name, | 373 cache_name, |
| 374 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, | 374 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, |
| 375 weak_factory_.GetWeakPtr(), | 375 weak_factory_.GetWeakPtr(), |
| 376 cache_name, | 376 cache_name, |
| 377 callback)); | 377 callback)); |
| 378 } | 378 } |
| 379 | 379 |
| 380 void ServiceWorkerCacheStorage::GetCache( | 380 void ServiceWorkerCacheStorage::GetCache( |
| 381 const std::string& cache_name, | 381 const std::string& cache_name, |
| 382 const CacheAndErrorCallback& callback) { | 382 const CacheAndErrorCallback& callback) { |
| 383 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 383 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 384 | 384 |
| 385 if (!initialized_) { | 385 if (!initialized_) { |
| 386 LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache, | 386 LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache, |
| 387 weak_factory_.GetWeakPtr(), | 387 weak_factory_.GetWeakPtr(), |
| 388 cache_name, | 388 cache_name, |
| 389 callback)); | 389 callback)); |
| 390 return; | 390 return; |
| 391 } | 391 } |
| 392 | 392 |
| 393 CacheContext* cache_context = GetLoadedCache(cache_name); | 393 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name); |
| 394 if (!cache_context) { | 394 if (!cache.get()) { |
| 395 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_NOT_FOUND); | 395 callback.Run(scoped_refptr<ServiceWorkerCache>(), |
| 396 CACHE_STORAGE_ERROR_NOT_FOUND); |
| 396 return; | 397 return; |
| 397 } | 398 } |
| 398 | 399 |
| 399 callback.Run(cache_context->id, CACHE_STORAGE_ERROR_NO_ERROR); | 400 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); |
| 400 } | 401 } |
| 401 | 402 |
| 402 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, | 403 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, |
| 403 const BoolAndErrorCallback& callback) { | 404 const BoolAndErrorCallback& callback) { |
| 404 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 405 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 405 | 406 |
| 406 if (!initialized_) { | 407 if (!initialized_) { |
| 407 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, | 408 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, |
| 408 weak_factory_.GetWeakPtr(), | 409 weak_factory_.GetWeakPtr(), |
| 409 cache_name, | 410 cache_name, |
| 410 callback)); | 411 callback)); |
| 411 return; | 412 return; |
| 412 } | 413 } |
| 413 | 414 |
| 414 bool has_cache = GetLoadedCache(cache_name) != NULL; | 415 bool has_cache = cache_map_.find(cache_name) != cache_map_.end(); |
| 415 | 416 |
| 416 callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR); | 417 callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR); |
| 417 } | 418 } |
| 418 | 419 |
| 419 void ServiceWorkerCacheStorage::DeleteCache( | 420 void ServiceWorkerCacheStorage::DeleteCache( |
| 420 const std::string& cache_name, | 421 const std::string& cache_name, |
| 421 const BoolAndErrorCallback& callback) { | 422 const BoolAndErrorCallback& callback) { |
| 422 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 423 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 423 | 424 |
| 424 if (!initialized_) { | 425 if (!initialized_) { |
| 425 LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache, | 426 LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache, |
| 426 weak_factory_.GetWeakPtr(), | 427 weak_factory_.GetWeakPtr(), |
| 427 cache_name, | 428 cache_name, |
| 428 callback)); | 429 callback)); |
| 429 return; | 430 return; |
| 430 } | 431 } |
| 431 | 432 |
| 432 scoped_ptr<CacheContext> cache_context(GetLoadedCache(cache_name)); | 433 |
| 433 if (!cache_context) { | 434 CacheMap::iterator it = cache_map_.find(cache_name); |
| 435 if (it == cache_map_.end()) { |
| 434 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); | 436 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); |
| 435 return; | 437 return; |
| 436 } | 438 } |
| 437 | 439 |
| 438 name_map_.erase(cache_name); | 440 base::WeakPtr<ServiceWorkerCache> cache = it->second; |
| 439 cache_map_.erase(cache_context->id); | 441 if (cache) |
| 440 cache_context.reset(); | 442 cache->Close(); |
| 443 |
| 444 cache_map_.erase(it); |
| 441 | 445 |
| 442 // Update the Index | 446 // Update the Index |
| 443 cache_loader_->WriteIndex( | 447 cache_loader_->WriteIndex( |
| 444 cache_map_, | 448 cache_map_, |
| 445 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, | 449 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, |
| 446 weak_factory_.GetWeakPtr(), | 450 weak_factory_.GetWeakPtr(), |
| 447 cache_name, | 451 cache_name, |
| 448 callback)); | 452 callback)); |
| 449 } | 453 } |
| 450 | 454 |
| 451 void ServiceWorkerCacheStorage::EnumerateCaches( | 455 void ServiceWorkerCacheStorage::EnumerateCaches( |
| 452 const StringsAndErrorCallback& callback) { | 456 const StringsAndErrorCallback& callback) { |
| 453 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 457 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 454 | 458 |
| 455 if (!initialized_) { | 459 if (!initialized_) { |
| 456 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, | 460 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, |
| 457 weak_factory_.GetWeakPtr(), | 461 weak_factory_.GetWeakPtr(), |
| 458 callback)); | 462 callback)); |
| 459 return; | 463 return; |
| 460 } | 464 } |
| 461 | 465 |
| 462 std::vector<std::string> names; | 466 std::vector<std::string> names; |
| 463 for (NameMap::const_iterator it = name_map_.begin(); it != name_map_.end(); | 467 for (CacheMap::const_iterator it = cache_map_.begin(); it != cache_map_.end(); |
| 464 ++it) { | 468 ++it) { |
| 465 names.push_back(it->first); | 469 names.push_back(it->first); |
| 466 } | 470 } |
| 467 | 471 |
| 468 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR); | 472 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR); |
| 469 } | 473 } |
| 470 | 474 |
| 471 // Init is run lazily so that it is called on the proper MessageLoop. | 475 // Init is run lazily so that it is called on the proper MessageLoop. |
| 472 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { | 476 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { |
| 473 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 477 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 493 base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex, | 497 base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex, |
| 494 weak_factory_.GetWeakPtr(), | 498 weak_factory_.GetWeakPtr(), |
| 495 callback)); | 499 callback)); |
| 496 } | 500 } |
| 497 | 501 |
| 498 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex( | 502 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex( |
| 499 const base::Closure& callback, | 503 const base::Closure& callback, |
| 500 scoped_ptr<std::vector<std::string> > indexed_cache_names) { | 504 scoped_ptr<std::vector<std::string> > indexed_cache_names) { |
| 501 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 505 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 502 | 506 |
| 503 for (std::vector<std::string>::iterator it = indexed_cache_names->begin(); | 507 |
| 504 it != indexed_cache_names->end(); | 508 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) { |
| 505 ++it) { | 509 cache_map_.insert(std::make_pair(indexed_cache_names->at(i), |
| 506 scoped_ptr<ServiceWorkerCache> cache = | 510 base::WeakPtr<ServiceWorkerCache>())); |
| 507 cache_loader_->CreateServiceWorkerCache(*it); | |
| 508 if (!cache) | |
| 509 continue; | |
| 510 AddCacheToMaps(*it, cache.Pass()); | |
| 511 } | 511 } |
| 512 | 512 |
| 513 initialized_ = true; | 513 initialized_ = true; |
| 514 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); | 514 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
| 515 it != init_callbacks_.end(); | 515 it != init_callbacks_.end(); |
| 516 ++it) { | 516 ++it) { |
| 517 it->Run(); | 517 it->Run(); |
| 518 } | 518 } |
| 519 init_callbacks_.clear(); | 519 init_callbacks_.clear(); |
| 520 } | 520 } |
| 521 | 521 |
| 522 ServiceWorkerCacheStorage::CacheContext* | |
| 523 ServiceWorkerCacheStorage::AddCacheToMaps( | |
| 524 const std::string& cache_name, | |
| 525 scoped_ptr<ServiceWorkerCache> cache) { | |
| 526 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 527 | |
| 528 CacheID id = next_cache_id_++; | |
| 529 CacheContext* cache_context = new CacheContext(cache_name, id, cache.Pass()); | |
| 530 cache_map_.insert(std::make_pair(id, cache_context)); // Takes ownership | |
| 531 name_map_.insert(std::make_pair(cache_name, id)); | |
| 532 return cache_context; | |
| 533 } | |
| 534 | |
| 535 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( | 522 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( |
| 536 const std::string& cache_name, | 523 const std::string& cache_name, |
| 537 const CacheAndErrorCallback& callback, | 524 const CacheAndErrorCallback& callback, |
| 538 scoped_ptr<ServiceWorkerCache> cache) { | 525 const scoped_refptr<ServiceWorkerCache>& cache) { |
| 539 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 526 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 540 | 527 |
| 541 if (!cache) { | 528 if (!cache.get()) { |
| 542 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_CLOSING); | 529 callback.Run(scoped_refptr<ServiceWorkerCache>(), |
| 530 CACHE_STORAGE_ERROR_CLOSING); |
| 543 return; | 531 return; |
| 544 } | 532 } |
| 545 | 533 |
| 546 CacheContext* cache_context = AddCacheToMaps(cache_name, cache.Pass()); | 534 cache_map_.insert(std::make_pair(cache_name, cache->AsWeakPtr())); |
| 547 | 535 |
| 548 cache_loader_->WriteIndex( | 536 cache_loader_->WriteIndex( |
| 549 cache_map_, | 537 cache_map_, |
| 550 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, | 538 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, |
| 551 weak_factory_.GetWeakPtr(), | 539 weak_factory_.GetWeakPtr(), |
| 552 callback, | 540 callback, |
| 553 cache_context->cache->AsWeakPtr(), | 541 cache)); |
| 554 cache_context->id)); | |
| 555 } | 542 } |
| 556 | 543 |
| 557 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( | 544 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( |
| 558 const CacheAndErrorCallback& callback, | 545 const CacheAndErrorCallback& callback, |
| 559 base::WeakPtr<ServiceWorkerCache> cache, | 546 const scoped_refptr<ServiceWorkerCache>& cache, |
| 560 CacheID id, | |
| 561 bool success) { | 547 bool success) { |
| 562 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 548 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 563 if (!cache) { | 549 DCHECK(cache.get()); |
| 564 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_CLOSING); | |
| 565 return; | |
| 566 } | |
| 567 | 550 |
| 568 callback.Run(id, CACHE_STORAGE_ERROR_NO_ERROR); | 551 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR); |
| 569 } | 552 } |
| 570 | 553 |
| 571 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex( | 554 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex( |
| 572 const std::string& cache_name, | 555 const std::string& cache_name, |
| 573 const BoolAndErrorCallback& callback, | 556 const BoolAndErrorCallback& callback, |
| 574 bool success) { | 557 bool success) { |
| 575 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 558 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 576 | 559 |
| 577 cache_loader_->CleanUpDeletedCache( | 560 cache_loader_->CleanUpDeletedCache( |
| 578 cache_name, | 561 cache_name, |
| 579 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp, | 562 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp, |
| 580 weak_factory_.GetWeakPtr(), | 563 weak_factory_.GetWeakPtr(), |
| 581 callback)); | 564 callback)); |
| 582 } | 565 } |
| 583 | 566 |
| 584 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( | 567 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( |
| 585 const BoolAndErrorCallback& callback, | 568 const BoolAndErrorCallback& callback, |
| 586 bool success) { | 569 bool success) { |
| 587 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 570 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 588 | 571 |
| 589 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); | 572 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); |
| 590 } | 573 } |
| 591 | 574 |
| 592 ServiceWorkerCacheStorage::CacheContext* | 575 scoped_refptr<ServiceWorkerCache> ServiceWorkerCacheStorage::GetLoadedCache( |
| 593 ServiceWorkerCacheStorage::GetLoadedCache(const std::string& cache_name) const { | 576 const std::string& cache_name) { |
| 594 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 577 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 595 DCHECK(initialized_); | 578 DCHECK(initialized_); |
| 596 | 579 |
| 597 NameMap::const_iterator name_iter = name_map_.find(cache_name); | 580 CacheMap::iterator map_iter = cache_map_.find(cache_name); |
| 598 if (name_iter == name_map_.end()) | 581 if (map_iter == cache_map_.end()) |
| 599 return NULL; | 582 return scoped_refptr<ServiceWorkerCache>(); |
| 600 | 583 |
| 601 CacheMap::const_iterator map_iter = cache_map_.find(name_iter->second); | 584 base::WeakPtr<ServiceWorkerCache> cache = map_iter->second; |
| 602 DCHECK(map_iter != cache_map_.end()); | 585 |
| 603 return map_iter->second; | 586 if (!cache) { |
| 587 scoped_refptr<ServiceWorkerCache> new_cache = |
| 588 cache_loader_->CreateServiceWorkerCache(cache_name); |
| 589 map_iter->second = new_cache->AsWeakPtr(); |
| 590 return new_cache; |
| 591 } |
| 592 |
| 593 return make_scoped_refptr(cache.get()); |
| 604 } | 594 } |
| 605 | 595 |
| 606 } // namespace content | 596 } // namespace content |
| OLD | NEW |