| 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/file_util.h" | 9 #include "base/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/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 15 #include "content/browser/service_worker/service_worker_cache.h" | 16 #include "content/browser/service_worker/service_worker_cache.h" |
| 16 #include "content/browser/service_worker/service_worker_cache.pb.h" | 17 #include "content/browser/service_worker/service_worker_cache.pb.h" |
| 17 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
| 18 #include "net/base/directory_lister.h" | 19 #include "net/base/directory_lister.h" |
| 19 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
| 20 #include "webkit/browser/blob/blob_storage_context.h" | 21 #include "webkit/browser/blob/blob_storage_context.h" |
| 21 | 22 |
| 22 namespace content { | 23 namespace content { |
| 23 | 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 |
| 24 // Handles the loading and clean up of ServiceWorkerCache objects. | 42 // Handles the loading and clean up of ServiceWorkerCache objects. |
| 25 class ServiceWorkerCacheStorage::CacheLoader | 43 class ServiceWorkerCacheStorage::CacheLoader |
| 26 : public base::RefCountedThreadSafe< | 44 : public base::RefCountedThreadSafe< |
| 27 ServiceWorkerCacheStorage::CacheLoader> { | 45 ServiceWorkerCacheStorage::CacheLoader> { |
| 28 public: | 46 public: |
| 29 typedef base::Callback<void(scoped_ptr<ServiceWorkerCache>)> CacheCallback; | 47 typedef base::Callback<void(scoped_ptr<ServiceWorkerCache>)> CacheCallback; |
| 30 typedef base::Callback<void(bool)> BoolCallback; | 48 typedef base::Callback<void(bool)> BoolCallback; |
| 31 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> | 49 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> |
| 32 StringsCallback; | 50 StringsCallback; |
| 33 | 51 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 46 // Deletes any pre-existing cache of the same name and then loads it. | 64 // Deletes any pre-existing cache of the same name and then loads it. |
| 47 virtual void CreateCache(const std::string& cache_name, | 65 virtual void CreateCache(const std::string& cache_name, |
| 48 const CacheCallback& callback) = 0; | 66 const CacheCallback& callback) = 0; |
| 49 | 67 |
| 50 // After the backend has been deleted, do any extra house keeping such as | 68 // After the backend has been deleted, do any extra house keeping such as |
| 51 // removing the cache's directory. | 69 // removing the cache's directory. |
| 52 virtual void CleanUpDeletedCache(const std::string& key, | 70 virtual void CleanUpDeletedCache(const std::string& key, |
| 53 const BoolCallback& callback) = 0; | 71 const BoolCallback& callback) = 0; |
| 54 | 72 |
| 55 // Writes the cache names (and sizes) to disk if applicable. | 73 // Writes the cache names (and sizes) to disk if applicable. |
| 56 virtual void WriteIndex(CacheMap* caches, const BoolCallback& callback) = 0; | 74 virtual void WriteIndex(const CacheMap& caches, |
| 75 const BoolCallback& callback) = 0; |
| 57 | 76 |
| 58 // Loads the cache names from disk if applicable. | 77 // Loads the cache names from disk if applicable. |
| 59 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 78 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
| 60 const StringsCallback& callback) = 0; | 79 const StringsCallback& callback) = 0; |
| 61 | 80 |
| 62 protected: | 81 protected: |
| 63 friend class base::RefCountedThreadSafe< | 82 friend class base::RefCountedThreadSafe< |
| 64 ServiceWorkerCacheStorage::CacheLoader>; | 83 ServiceWorkerCacheStorage::CacheLoader>; |
| 65 | 84 |
| 66 virtual ~CacheLoader() {} | 85 virtual ~CacheLoader() {} |
| (...skipping 12 matching lines...) Expand all Loading... |
| 79 base::WeakPtr<storage::BlobStorageContext> blob_context) | 98 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 80 : CacheLoader(cache_task_runner, request_context, blob_context) {} | 99 : CacheLoader(cache_task_runner, request_context, blob_context) {} |
| 81 virtual void LoadCache(const std::string& cache_name, | 100 virtual void LoadCache(const std::string& cache_name, |
| 82 const CacheCallback& callback) OVERRIDE { | 101 const CacheCallback& callback) OVERRIDE { |
| 83 NOTREACHED(); | 102 NOTREACHED(); |
| 84 } | 103 } |
| 85 | 104 |
| 86 virtual void CreateCache(const std::string& cache_name, | 105 virtual void CreateCache(const std::string& cache_name, |
| 87 const CacheCallback& callback) OVERRIDE { | 106 const CacheCallback& callback) OVERRIDE { |
| 88 scoped_ptr<ServiceWorkerCache> cache = | 107 scoped_ptr<ServiceWorkerCache> cache = |
| 89 ServiceWorkerCache::CreateMemoryCache( | 108 ServiceWorkerCache::CreateMemoryCache(request_context_, blob_context_); |
| 90 cache_name, request_context_, blob_context_); | |
| 91 callback.Run(cache.Pass()); | 109 callback.Run(cache.Pass()); |
| 92 } | 110 } |
| 93 | 111 |
| 94 virtual void CleanUpDeletedCache(const std::string& cache_name, | 112 virtual void CleanUpDeletedCache(const std::string& cache_name, |
| 95 const BoolCallback& callback) OVERRIDE { | 113 const BoolCallback& callback) OVERRIDE { |
| 96 callback.Run(true); | 114 callback.Run(true); |
| 97 } | 115 } |
| 98 | 116 |
| 99 virtual void WriteIndex(CacheMap* caches, | 117 virtual void WriteIndex(const CacheMap& caches, |
| 100 const BoolCallback& callback) OVERRIDE { | 118 const BoolCallback& callback) OVERRIDE { |
| 101 callback.Run(false); | 119 callback.Run(false); |
| 102 } | 120 } |
| 103 | 121 |
| 104 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 122 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
| 105 const StringsCallback& callback) OVERRIDE { | 123 const StringsCallback& callback) OVERRIDE { |
| 106 callback.Run(cache_names.Pass()); | 124 callback.Run(cache_names.Pass()); |
| 107 } | 125 } |
| 108 | 126 |
| 109 private: | 127 private: |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 178 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 161 | 179 |
| 162 if (!dir_rv) { | 180 if (!dir_rv) { |
| 163 callback.Run(scoped_ptr<ServiceWorkerCache>()); | 181 callback.Run(scoped_ptr<ServiceWorkerCache>()); |
| 164 return; | 182 return; |
| 165 } | 183 } |
| 166 | 184 |
| 167 scoped_ptr<ServiceWorkerCache> cache = | 185 scoped_ptr<ServiceWorkerCache> cache = |
| 168 ServiceWorkerCache::CreatePersistentCache( | 186 ServiceWorkerCache::CreatePersistentCache( |
| 169 CreatePersistentCachePath(origin_path_, cache_name), | 187 CreatePersistentCachePath(origin_path_, cache_name), |
| 170 cache_name, | |
| 171 request_context_, | 188 request_context_, |
| 172 blob_context_); | 189 blob_context_); |
| 173 callback.Run(cache.Pass()); | 190 callback.Run(cache.Pass()); |
| 174 } | 191 } |
| 175 | 192 |
| 176 virtual void CreateCache(const std::string& cache_name, | 193 virtual void CreateCache(const std::string& cache_name, |
| 177 const CacheCallback& callback) OVERRIDE { | 194 const CacheCallback& callback) OVERRIDE { |
| 178 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 195 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 179 | 196 |
| 180 // 1. Delete the cache's directory if it exists. | 197 // 1. Delete the cache's directory if it exists. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 void CleanUpDeleteCacheDirInPool( | 253 void CleanUpDeleteCacheDirInPool( |
| 237 const base::FilePath& cache_path, | 254 const base::FilePath& cache_path, |
| 238 const BoolCallback& callback, | 255 const BoolCallback& callback, |
| 239 const scoped_refptr<base::MessageLoopProxy>& original_loop) { | 256 const scoped_refptr<base::MessageLoopProxy>& original_loop) { |
| 240 DCHECK(cache_task_runner_->RunsTasksOnCurrentThread()); | 257 DCHECK(cache_task_runner_->RunsTasksOnCurrentThread()); |
| 241 | 258 |
| 242 bool rv = base::DeleteFile(cache_path, true); | 259 bool rv = base::DeleteFile(cache_path, true); |
| 243 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv)); | 260 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv)); |
| 244 } | 261 } |
| 245 | 262 |
| 246 virtual void WriteIndex(CacheMap* caches, | 263 virtual void WriteIndex(const CacheMap& caches, |
| 247 const BoolCallback& callback) OVERRIDE { | 264 const BoolCallback& callback) OVERRIDE { |
| 248 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 265 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 249 | 266 |
| 250 // 1. Create the index file as a string. (WriteIndex) | 267 // 1. Create the index file as a string. (WriteIndex) |
| 251 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) | 268 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) |
| 252 | 269 |
| 253 ServiceWorkerCacheStorageIndex index; | 270 ServiceWorkerCacheStorageIndex index; |
| 254 | 271 |
| 255 for (CacheMap::const_iterator iter(caches); !iter.IsAtEnd(); | 272 for (CacheMap::const_iterator it = caches.begin(); it != caches.end(); |
| 256 iter.Advance()) { | 273 ++it) { |
| 257 const ServiceWorkerCache* cache = iter.GetCurrentValue(); | 274 const CacheContext* cache = it->second; |
| 258 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); | 275 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); |
| 259 index_cache->set_name(cache->name()); | 276 index_cache->set_name(cache->name); |
| 260 index_cache->set_size(0); // TODO(jkarlin): Make this real. | 277 index_cache->set_size(0); // TODO(jkarlin): Make this real. |
| 261 } | 278 } |
| 262 | 279 |
| 263 std::string serialized; | 280 std::string serialized; |
| 264 bool success = index.SerializeToString(&serialized); | 281 bool success = index.SerializeToString(&serialized); |
| 265 DCHECK(success); | 282 DCHECK(success); |
| 266 | 283 |
| 267 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); | 284 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); |
| 268 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); | 285 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); |
| 269 | 286 |
| 270 cache_task_runner_->PostTask( | 287 cache_task_runner_->PostTask( |
| 271 FROM_HERE, | 288 FROM_HERE, |
| 272 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, | 289 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, |
| 273 this, | 290 this, |
| 274 tmp_path, | 291 tmp_path, |
| 275 index_path, | 292 index_path, |
| 276 serialized, | 293 serialized, |
| 277 caches, | |
| 278 callback, | 294 callback, |
| 279 base::MessageLoopProxy::current())); | 295 base::MessageLoopProxy::current())); |
| 280 } | 296 } |
| 281 | 297 |
| 282 void WriteIndexWriteToFileInPool( | 298 void WriteIndexWriteToFileInPool( |
| 283 const base::FilePath& tmp_path, | 299 const base::FilePath& tmp_path, |
| 284 const base::FilePath& index_path, | 300 const base::FilePath& index_path, |
| 285 const std::string& data, | 301 const std::string& data, |
| 286 CacheMap* caches, | |
| 287 const BoolCallback& callback, | 302 const BoolCallback& callback, |
| 288 const scoped_refptr<base::MessageLoopProxy>& original_loop) { | 303 const scoped_refptr<base::MessageLoopProxy>& original_loop) { |
| 289 DCHECK(cache_task_runner_->RunsTasksOnCurrentThread()); | 304 DCHECK(cache_task_runner_->RunsTasksOnCurrentThread()); |
| 290 | 305 |
| 291 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); | 306 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size()); |
| 292 if (bytes_written != implicit_cast<int>(data.size())) { | 307 if (bytes_written != implicit_cast<int>(data.size())) { |
| 293 base::DeleteFile(tmp_path, /* recursive */ false); | 308 base::DeleteFile(tmp_path, /* recursive */ false); |
| 294 original_loop->PostTask(FROM_HERE, base::Bind(callback, false)); | 309 original_loop->PostTask(FROM_HERE, base::Bind(callback, false)); |
| 295 } | 310 } |
| 296 | 311 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 const base::FilePath origin_path_; | 387 const base::FilePath origin_path_; |
| 373 }; | 388 }; |
| 374 | 389 |
| 375 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( | 390 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( |
| 376 const base::FilePath& path, | 391 const base::FilePath& path, |
| 377 bool memory_only, | 392 bool memory_only, |
| 378 base::SequencedTaskRunner* cache_task_runner, | 393 base::SequencedTaskRunner* cache_task_runner, |
| 379 net::URLRequestContext* request_context, | 394 net::URLRequestContext* request_context, |
| 380 base::WeakPtr<storage::BlobStorageContext> blob_context) | 395 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 381 : initialized_(false), | 396 : initialized_(false), |
| 397 next_cache_id_(0), |
| 382 origin_path_(path), | 398 origin_path_(path), |
| 383 cache_task_runner_(cache_task_runner), | 399 cache_task_runner_(cache_task_runner), |
| 384 weak_factory_(this) { | 400 weak_factory_(this) { |
| 385 if (memory_only) | 401 if (memory_only) |
| 386 cache_loader_ = new MemoryLoader( | 402 cache_loader_ = new MemoryLoader( |
| 387 cache_task_runner_.get(), request_context, blob_context); | 403 cache_task_runner_.get(), request_context, blob_context); |
| 388 else | 404 else |
| 389 cache_loader_ = new SimpleCacheLoader( | 405 cache_loader_ = new SimpleCacheLoader( |
| 390 origin_path_, cache_task_runner_.get(), request_context, blob_context); | 406 origin_path_, cache_task_runner_.get(), request_context, blob_context); |
| 391 } | 407 } |
| 392 | 408 |
| 393 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { | 409 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { |
| 410 STLDeleteContainerPairSecondPointers(cache_map_.begin(), cache_map_.end()); |
| 394 } | 411 } |
| 395 | 412 |
| 396 void ServiceWorkerCacheStorage::CreateCache( | 413 void ServiceWorkerCacheStorage::CreateCache( |
| 397 const std::string& cache_name, | 414 const std::string& cache_name, |
| 398 const CacheAndErrorCallback& callback) { | 415 const CacheAndErrorCallback& callback) { |
| 399 if (!initialized_) { | 416 if (!initialized_) { |
| 400 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, | 417 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, |
| 401 weak_factory_.GetWeakPtr(), | 418 weak_factory_.GetWeakPtr(), |
| 402 cache_name, | 419 cache_name, |
| 403 callback)); | 420 callback)); |
| 404 return; | 421 return; |
| 405 } | 422 } |
| 406 | 423 |
| 407 if (cache_name.empty()) { | 424 if (cache_name.empty()) { |
| 408 callback.Run(0, CACHE_STORAGE_ERROR_EMPTY_KEY); | 425 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_EMPTY_KEY); |
| 409 return; | 426 return; |
| 410 } | 427 } |
| 411 | 428 |
| 412 if (GetLoadedCache(cache_name)) { | 429 if (GetLoadedCache(cache_name)) { |
| 413 callback.Run(0, CACHE_STORAGE_ERROR_EXISTS); | 430 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_EXISTS); |
| 414 return; | 431 return; |
| 415 } | 432 } |
| 416 | 433 |
| 417 cache_loader_->CreateCache( | 434 cache_loader_->CreateCache( |
| 418 cache_name, | 435 cache_name, |
| 419 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, | 436 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache, |
| 420 weak_factory_.GetWeakPtr(), | 437 weak_factory_.GetWeakPtr(), |
| 421 cache_name, | 438 cache_name, |
| 422 callback)); | 439 callback)); |
| 423 } | 440 } |
| 424 | 441 |
| 425 void ServiceWorkerCacheStorage::GetCache( | 442 void ServiceWorkerCacheStorage::GetCache( |
| 426 const std::string& cache_name, | 443 const std::string& cache_name, |
| 427 const CacheAndErrorCallback& callback) { | 444 const CacheAndErrorCallback& callback) { |
| 428 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 445 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 429 | 446 |
| 430 if (!initialized_) { | 447 if (!initialized_) { |
| 431 LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache, | 448 LazyInit(base::Bind(&ServiceWorkerCacheStorage::GetCache, |
| 432 weak_factory_.GetWeakPtr(), | 449 weak_factory_.GetWeakPtr(), |
| 433 cache_name, | 450 cache_name, |
| 434 callback)); | 451 callback)); |
| 435 return; | 452 return; |
| 436 } | 453 } |
| 437 | 454 |
| 438 if (cache_name.empty()) { | 455 if (cache_name.empty()) { |
| 439 callback.Run(0, CACHE_STORAGE_ERROR_EMPTY_KEY); | 456 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_EMPTY_KEY); |
| 440 return; | 457 return; |
| 441 } | 458 } |
| 442 | 459 |
| 443 ServiceWorkerCache* cache = GetLoadedCache(cache_name); | 460 CacheContext* cache_context = GetLoadedCache(cache_name); |
| 444 if (!cache) { | 461 if (!cache_context) { |
| 445 callback.Run(0, CACHE_STORAGE_ERROR_NOT_FOUND); | 462 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_NOT_FOUND); |
| 446 return; | 463 return; |
| 447 } | 464 } |
| 448 | 465 |
| 466 ServiceWorkerCache* cache = cache_context->cache.get(); |
| 467 |
| 449 if (cache->HasCreatedBackend()) | 468 if (cache->HasCreatedBackend()) |
| 450 return callback.Run(cache->id(), CACHE_STORAGE_ERROR_NO_ERROR); | 469 return callback.Run(cache_context->id, CACHE_STORAGE_ERROR_NO_ERROR); |
| 451 | 470 |
| 452 cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend, | 471 cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend, |
| 453 weak_factory_.GetWeakPtr(), | 472 weak_factory_.GetWeakPtr(), |
| 454 cache->AsWeakPtr(), | 473 cache->AsWeakPtr(), |
| 474 cache_context->id, |
| 455 callback)); | 475 callback)); |
| 456 } | 476 } |
| 457 | 477 |
| 458 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, | 478 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name, |
| 459 const BoolAndErrorCallback& callback) { | 479 const BoolAndErrorCallback& callback) { |
| 460 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 480 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 461 | 481 |
| 462 if (!initialized_) { | 482 if (!initialized_) { |
| 463 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, | 483 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache, |
| 464 weak_factory_.GetWeakPtr(), | 484 weak_factory_.GetWeakPtr(), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 488 cache_name, | 508 cache_name, |
| 489 callback)); | 509 callback)); |
| 490 return; | 510 return; |
| 491 } | 511 } |
| 492 | 512 |
| 493 if (cache_name.empty()) { | 513 if (cache_name.empty()) { |
| 494 callback.Run(false, CACHE_STORAGE_ERROR_EMPTY_KEY); | 514 callback.Run(false, CACHE_STORAGE_ERROR_EMPTY_KEY); |
| 495 return; | 515 return; |
| 496 } | 516 } |
| 497 | 517 |
| 498 ServiceWorkerCache* cache = GetLoadedCache(cache_name); | 518 scoped_ptr<CacheContext> cache_context(GetLoadedCache(cache_name)); |
| 499 if (!cache) { | 519 if (!cache_context) { |
| 500 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); | 520 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); |
| 501 return; | 521 return; |
| 502 } | 522 } |
| 503 | 523 |
| 504 name_map_.erase(cache_name); | 524 name_map_.erase(cache_name); |
| 505 cache_map_.Remove(cache->id()); // deletes cache | 525 cache_map_.erase(cache_context->id); |
| 526 cache_context.reset(); |
| 506 | 527 |
| 507 // Update the Index | 528 // Update the Index |
| 508 cache_loader_->WriteIndex( | 529 cache_loader_->WriteIndex( |
| 509 &cache_map_, | 530 cache_map_, |
| 510 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, | 531 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex, |
| 511 weak_factory_.GetWeakPtr(), | 532 weak_factory_.GetWeakPtr(), |
| 512 cache_name, | 533 cache_name, |
| 513 callback)); | 534 callback)); |
| 514 } | 535 } |
| 515 | 536 |
| 516 void ServiceWorkerCacheStorage::EnumerateCaches( | 537 void ServiceWorkerCacheStorage::EnumerateCaches( |
| 517 const StringsAndErrorCallback& callback) { | 538 const StringsAndErrorCallback& callback) { |
| 518 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 539 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 519 | 540 |
| 520 if (!initialized_) { | 541 if (!initialized_) { |
| 521 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, | 542 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, |
| 522 weak_factory_.GetWeakPtr(), | 543 weak_factory_.GetWeakPtr(), |
| 523 callback)); | 544 callback)); |
| 524 return; | 545 return; |
| 525 } | 546 } |
| 526 | 547 |
| 527 std::vector<std::string> names; | 548 std::vector<std::string> names; |
| 528 for (NameMap::const_iterator it = name_map_.begin(); it != name_map_.end(); | 549 for (NameMap::const_iterator it = name_map_.begin(); it != name_map_.end(); |
| 529 ++it) { | 550 ++it) { |
| 530 names.push_back(it->first); | 551 names.push_back(it->first); |
| 531 } | 552 } |
| 532 | 553 |
| 533 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR); | 554 callback.Run(names, CACHE_STORAGE_ERROR_NO_ERROR); |
| 534 } | 555 } |
| 535 | 556 |
| 536 void ServiceWorkerCacheStorage::DidCreateBackend( | 557 void ServiceWorkerCacheStorage::DidCreateBackend( |
| 537 base::WeakPtr<ServiceWorkerCache> cache, | 558 base::WeakPtr<ServiceWorkerCache> cache, |
| 559 CacheID cache_id, |
| 538 const CacheAndErrorCallback& callback, | 560 const CacheAndErrorCallback& callback, |
| 539 ServiceWorkerCache::ErrorType error) { | 561 ServiceWorkerCache::ErrorType error) { |
| 540 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 562 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 541 | 563 |
| 542 if (error != ServiceWorkerCache::ErrorTypeOK || !cache) { | 564 if (error != ServiceWorkerCache::ErrorTypeOK || !cache) { |
| 543 // TODO(jkarlin): This should delete the directory and try again in case | 565 // TODO(jkarlin): This should delete the directory and try again in case |
| 544 // the cache is simply corrupt. | 566 // the cache is simply corrupt. |
| 545 callback.Run(0, CACHE_STORAGE_ERROR_STORAGE); | 567 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_STORAGE); |
| 546 return; | 568 return; |
| 547 } | 569 } |
| 548 | 570 |
| 549 callback.Run(cache->id(), CACHE_STORAGE_ERROR_NO_ERROR); | 571 callback.Run(cache_id, CACHE_STORAGE_ERROR_NO_ERROR); |
| 550 } | 572 } |
| 551 | 573 |
| 552 // Init is run lazily so that it is called on the proper MessageLoop. | 574 // Init is run lazily so that it is called on the proper MessageLoop. |
| 553 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { | 575 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { |
| 554 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 576 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 555 DCHECK(!initialized_); | 577 DCHECK(!initialized_); |
| 556 | 578 |
| 557 init_callbacks_.push_back(callback); | 579 init_callbacks_.push_back(callback); |
| 558 | 580 |
| 559 // If this isn't the first call to LazyInit then return as the initialization | 581 // If this isn't the first call to LazyInit then return as the initialization |
| (...skipping 28 matching lines...) Expand all Loading... |
| 588 | 610 |
| 589 std::vector<std::string>::const_iterator iter = indexed_cache_names->begin(); | 611 std::vector<std::string>::const_iterator iter = indexed_cache_names->begin(); |
| 590 std::vector<std::string>::const_iterator iter_next = iter + 1; | 612 std::vector<std::string>::const_iterator iter_next = iter + 1; |
| 591 | 613 |
| 592 cache_loader_->LoadCache( | 614 cache_loader_->LoadCache( |
| 593 *iter, | 615 *iter, |
| 594 base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, | 616 base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, |
| 595 weak_factory_.GetWeakPtr(), | 617 weak_factory_.GetWeakPtr(), |
| 596 callback, | 618 callback, |
| 597 base::Passed(indexed_cache_names.Pass()), | 619 base::Passed(indexed_cache_names.Pass()), |
| 598 iter_next)); | 620 iter_next, |
| 621 *iter)); |
| 599 } | 622 } |
| 600 | 623 |
| 601 void ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName( | 624 void ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName( |
| 602 const base::Closure& callback, | 625 const base::Closure& callback, |
| 603 scoped_ptr<std::vector<std::string> > indexed_cache_names, | 626 scoped_ptr<std::vector<std::string> > indexed_cache_names, |
| 604 const std::vector<std::string>::const_iterator& iter, | 627 const std::vector<std::string>::const_iterator& iter, |
| 628 const std::string& cache_name, |
| 605 scoped_ptr<ServiceWorkerCache> cache) { | 629 scoped_ptr<ServiceWorkerCache> cache) { |
| 606 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 630 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 607 | 631 |
| 608 if (cache) | 632 if (cache) |
| 609 AddCacheToMaps(cache.Pass()); | 633 AddCacheToMaps(cache_name, cache.Pass()); |
| 610 | 634 |
| 611 if (iter == indexed_cache_names->end()) { | 635 if (iter == indexed_cache_names->end()) { |
| 612 LazyInitDone(); | 636 LazyInitDone(); |
| 613 return; | 637 return; |
| 614 } | 638 } |
| 615 | 639 |
| 616 std::vector<std::string>::const_iterator iter_next = iter + 1; | 640 std::vector<std::string>::const_iterator iter_next = iter + 1; |
| 617 cache_loader_->LoadCache( | 641 cache_loader_->LoadCache( |
| 618 *iter, | 642 *iter, |
| 619 base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, | 643 base::Bind(&ServiceWorkerCacheStorage::LazyInitIterateAndLoadCacheName, |
| 620 weak_factory_.GetWeakPtr(), | 644 weak_factory_.GetWeakPtr(), |
| 621 callback, | 645 callback, |
| 622 base::Passed(indexed_cache_names.Pass()), | 646 base::Passed(indexed_cache_names.Pass()), |
| 623 iter_next)); | 647 iter_next, |
| 648 *iter)); |
| 624 } | 649 } |
| 625 | 650 |
| 626 void ServiceWorkerCacheStorage::LazyInitDone() { | 651 void ServiceWorkerCacheStorage::LazyInitDone() { |
| 627 initialized_ = true; | 652 initialized_ = true; |
| 628 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); | 653 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin(); |
| 629 it != init_callbacks_.end(); | 654 it != init_callbacks_.end(); |
| 630 ++it) { | 655 ++it) { |
| 631 it->Run(); | 656 it->Run(); |
| 632 } | 657 } |
| 633 init_callbacks_.clear(); | 658 init_callbacks_.clear(); |
| 634 } | 659 } |
| 635 | 660 |
| 636 void ServiceWorkerCacheStorage::AddCacheToMaps( | 661 ServiceWorkerCacheStorage::CacheContext* |
| 662 ServiceWorkerCacheStorage::AddCacheToMaps( |
| 663 const std::string& cache_name, |
| 637 scoped_ptr<ServiceWorkerCache> cache) { | 664 scoped_ptr<ServiceWorkerCache> cache) { |
| 638 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 665 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 639 | 666 |
| 640 ServiceWorkerCache* cache_ptr = cache.release(); | 667 CacheID id = next_cache_id_++; |
| 641 CacheID id = cache_map_.Add(cache_ptr); | 668 CacheContext* cache_context = new CacheContext(cache_name, id, cache.Pass()); |
| 642 name_map_.insert(std::make_pair(cache_ptr->name(), id)); | 669 cache_map_.insert(std::make_pair(id, cache_context)); // Takes ownership |
| 643 cache_ptr->set_id(id); | 670 name_map_.insert(std::make_pair(cache_name, id)); |
| 671 return cache_context; |
| 644 } | 672 } |
| 645 | 673 |
| 646 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( | 674 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache( |
| 647 const std::string& cache_name, | 675 const std::string& cache_name, |
| 648 const CacheAndErrorCallback& callback, | 676 const CacheAndErrorCallback& callback, |
| 649 scoped_ptr<ServiceWorkerCache> cache) { | 677 scoped_ptr<ServiceWorkerCache> cache) { |
| 650 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 678 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 651 | 679 |
| 652 if (!cache) { | 680 if (!cache) { |
| 653 callback.Run(0, CACHE_STORAGE_ERROR_STORAGE); | 681 callback.Run(kInvalidCacheID, CACHE_STORAGE_ERROR_CLOSING); |
| 654 return; | 682 return; |
| 655 } | 683 } |
| 656 | 684 |
| 657 base::WeakPtr<ServiceWorkerCache> cache_ptr = cache->AsWeakPtr(); | 685 CacheContext* cache_context = AddCacheToMaps(cache_name, cache.Pass()); |
| 658 | |
| 659 AddCacheToMaps(cache.Pass()); | |
| 660 | 686 |
| 661 cache_loader_->WriteIndex( | 687 cache_loader_->WriteIndex( |
| 662 &cache_map_, | 688 cache_map_, |
| 663 base::Bind( | 689 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, |
| 664 &ServiceWorkerCacheStorage::CreateCacheDidWriteIndex, | 690 weak_factory_.GetWeakPtr(), |
| 665 weak_factory_.GetWeakPtr(), | 691 callback, |
| 666 callback, | 692 cache_context->cache->AsWeakPtr(), |
| 667 cache_ptr)); // cache is owned by this->CacheMap and won't be deleted | 693 cache_context->id)); |
| 668 } | 694 } |
| 669 | 695 |
| 670 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( | 696 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex( |
| 671 const CacheAndErrorCallback& callback, | 697 const CacheAndErrorCallback& callback, |
| 672 base::WeakPtr<ServiceWorkerCache> cache, | 698 base::WeakPtr<ServiceWorkerCache> cache, |
| 699 CacheID id, |
| 673 bool success) { | 700 bool success) { |
| 674 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 701 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 675 if (!cache) { | 702 if (!cache) { |
| 676 callback.Run(false, CACHE_STORAGE_ERROR_STORAGE); | 703 callback.Run(false, CACHE_STORAGE_ERROR_CLOSING); |
| 677 return; | 704 return; |
| 678 } | 705 } |
| 679 | 706 |
| 680 cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend, | 707 cache->CreateBackend(base::Bind(&ServiceWorkerCacheStorage::DidCreateBackend, |
| 681 weak_factory_.GetWeakPtr(), | 708 weak_factory_.GetWeakPtr(), |
| 682 cache, | 709 cache, |
| 710 id, |
| 683 callback)); | 711 callback)); |
| 684 } | 712 } |
| 685 | 713 |
| 686 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex( | 714 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex( |
| 687 const std::string& cache_name, | 715 const std::string& cache_name, |
| 688 const BoolAndErrorCallback& callback, | 716 const BoolAndErrorCallback& callback, |
| 689 bool success) { | 717 bool success) { |
| 690 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 718 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 691 | 719 |
| 692 cache_loader_->CleanUpDeletedCache( | 720 cache_loader_->CleanUpDeletedCache( |
| 693 cache_name, | 721 cache_name, |
| 694 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp, | 722 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp, |
| 695 weak_factory_.GetWeakPtr(), | 723 weak_factory_.GetWeakPtr(), |
| 696 callback)); | 724 callback)); |
| 697 } | 725 } |
| 698 | 726 |
| 699 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( | 727 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp( |
| 700 const BoolAndErrorCallback& callback, | 728 const BoolAndErrorCallback& callback, |
| 701 bool success) { | 729 bool success) { |
| 702 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 730 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 703 | 731 |
| 704 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); | 732 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR); |
| 705 } | 733 } |
| 706 | 734 |
| 707 ServiceWorkerCache* ServiceWorkerCacheStorage::GetLoadedCache( | 735 ServiceWorkerCacheStorage::CacheContext* |
| 708 const std::string& cache_name) const { | 736 ServiceWorkerCacheStorage::GetLoadedCache(const std::string& cache_name) const { |
| 709 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 737 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 710 DCHECK(initialized_); | 738 DCHECK(initialized_); |
| 711 | 739 |
| 712 NameMap::const_iterator it = name_map_.find(cache_name); | 740 NameMap::const_iterator name_iter = name_map_.find(cache_name); |
| 713 if (it == name_map_.end()) | 741 if (name_iter == name_map_.end()) |
| 714 return NULL; | 742 return NULL; |
| 715 | 743 |
| 716 ServiceWorkerCache* cache = cache_map_.Lookup(it->second); | 744 CacheMap::const_iterator map_iter = cache_map_.find(name_iter->second); |
| 717 DCHECK(cache); | 745 DCHECK(map_iter != cache_map_.end()); |
| 718 return cache; | 746 return map_iter->second; |
| 719 } | 747 } |
| 720 | 748 |
| 721 } // namespace content | 749 } // namespace content |
| OLD | NEW |