Rename isSystemLocationEnabled to isLocationEnabled, as per internal review (185995).
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_cache_storage.cc
blob539cafb2e23b275d7883390a0919374c3a5444cb
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
3 // found in the LICENSE file.
5 #include "content/browser/service_worker/service_worker_cache_storage.h"
7 #include <string>
9 #include "base/barrier_closure.h"
10 #include "base/files/file_util.h"
11 #include "base/files/memory_mapped_file.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/sha1.h"
14 #include "base/stl_util.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "content/browser/service_worker/service_worker_cache.h"
18 #include "content/browser/service_worker/service_worker_cache.pb.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "net/base/directory_lister.h"
21 #include "net/base/net_errors.h"
22 #include "storage/browser/blob/blob_storage_context.h"
23 #include "storage/browser/quota/quota_manager_proxy.h"
25 namespace content {
27 namespace {
29 void CloseAllCachesDidCloseCache(const scoped_refptr<ServiceWorkerCache>& cache,
30 const base::Closure& barrier_closure) {
31 barrier_closure.Run();
34 } // namespace
36 const char ServiceWorkerCacheStorage::kIndexFileName[] = "index.txt";
38 // Handles the loading and clean up of ServiceWorkerCache objects. The
39 // callback of every public method is guaranteed to be called.
40 class ServiceWorkerCacheStorage::CacheLoader {
41 public:
42 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)>
43 CacheCallback;
44 typedef base::Callback<void(bool)> BoolCallback;
45 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)>
46 StringVectorCallback;
48 CacheLoader(
49 base::SequencedTaskRunner* cache_task_runner,
50 net::URLRequestContext* request_context,
51 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
52 base::WeakPtr<storage::BlobStorageContext> blob_context,
53 const GURL& origin)
54 : cache_task_runner_(cache_task_runner),
55 request_context_(request_context),
56 quota_manager_proxy_(quota_manager_proxy),
57 blob_context_(blob_context),
58 origin_(origin) {
59 DCHECK(!origin_.is_empty());
62 virtual ~CacheLoader() {}
64 // Creates a ServiceWorkerCache with the given name. It does not attempt to
65 // load the backend, that happens lazily when the cache is used.
66 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache(
67 const std::string& cache_name) = 0;
69 // Deletes any pre-existing cache of the same name and then loads it.
70 virtual void CreateCache(const std::string& cache_name,
71 const CacheCallback& callback) = 0;
73 // After the backend has been deleted, do any extra house keeping such as
74 // removing the cache's directory.
75 virtual void CleanUpDeletedCache(const std::string& key,
76 const BoolCallback& callback) = 0;
78 // Writes the cache names (and sizes) to disk if applicable.
79 virtual void WriteIndex(const StringVector& cache_names,
80 const BoolCallback& callback) = 0;
82 // Loads the cache names from disk if applicable.
83 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names,
84 const StringVectorCallback& callback) = 0;
86 protected:
87 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_;
88 net::URLRequestContext* request_context_;
89 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_;
90 base::WeakPtr<storage::BlobStorageContext> blob_context_;
91 GURL origin_;
94 // Creates memory-only ServiceWorkerCaches. Because these caches have no
95 // persistent storage it is not safe to free them from memory if they might be
96 // used again. Therefore this class holds a reference to each cache until the
97 // cache is deleted.
98 class ServiceWorkerCacheStorage::MemoryLoader
99 : public ServiceWorkerCacheStorage::CacheLoader {
100 public:
101 MemoryLoader(
102 base::SequencedTaskRunner* cache_task_runner,
103 net::URLRequestContext* request_context,
104 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
105 base::WeakPtr<storage::BlobStorageContext> blob_context,
106 const GURL& origin)
107 : CacheLoader(cache_task_runner,
108 request_context,
109 quota_manager_proxy,
110 blob_context,
111 origin) {}
113 scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache(
114 const std::string& cache_name) override {
115 return ServiceWorkerCache::CreateMemoryCache(
116 origin_, request_context_, quota_manager_proxy_, blob_context_);
119 void CreateCache(const std::string& cache_name,
120 const CacheCallback& callback) override {
121 scoped_refptr<ServiceWorkerCache> cache =
122 CreateServiceWorkerCache(cache_name);
123 cache_refs_.insert(std::make_pair(cache_name, cache));
124 callback.Run(cache);
127 void CleanUpDeletedCache(const std::string& cache_name,
128 const BoolCallback& callback) override {
129 CacheRefMap::iterator it = cache_refs_.find(cache_name);
130 DCHECK(it != cache_refs_.end());
131 cache_refs_.erase(it);
132 callback.Run(true);
135 void WriteIndex(const StringVector& cache_names,
136 const BoolCallback& callback) override {
137 callback.Run(false);
140 void LoadIndex(scoped_ptr<std::vector<std::string>> cache_names,
141 const StringVectorCallback& callback) override {
142 callback.Run(cache_names.Pass());
145 private:
146 typedef std::map<std::string, scoped_refptr<ServiceWorkerCache> > CacheRefMap;
147 ~MemoryLoader() override {}
149 // Keep a reference to each cache to ensure that it's not freed before the
150 // client calls ServiceWorkerCacheStorage::Delete or the CacheStorage is
151 // freed.
152 CacheRefMap cache_refs_;
155 class ServiceWorkerCacheStorage::SimpleCacheLoader
156 : public ServiceWorkerCacheStorage::CacheLoader {
157 public:
158 SimpleCacheLoader(
159 const base::FilePath& origin_path,
160 base::SequencedTaskRunner* cache_task_runner,
161 net::URLRequestContext* request_context,
162 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
163 base::WeakPtr<storage::BlobStorageContext> blob_context,
164 const GURL& origin)
165 : CacheLoader(cache_task_runner,
166 request_context,
167 quota_manager_proxy,
168 blob_context,
169 origin),
170 origin_path_(origin_path),
171 weak_ptr_factory_(this) {}
173 scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache(
174 const std::string& cache_name) override {
175 DCHECK_CURRENTLY_ON(BrowserThread::IO);
177 return ServiceWorkerCache::CreatePersistentCache(
178 origin_,
179 CreatePersistentCachePath(origin_path_, cache_name),
180 request_context_,
181 quota_manager_proxy_,
182 blob_context_);
185 void CreateCache(const std::string& cache_name,
186 const CacheCallback& callback) override {
187 DCHECK_CURRENTLY_ON(BrowserThread::IO);
189 // 1. Delete the cache's directory if it exists.
190 // (CreateCacheDeleteFilesInPool)
191 // 2. Load the cache. (LoadCreateDirectoryInPool)
193 base::FilePath cache_path =
194 CreatePersistentCachePath(origin_path_, cache_name);
196 PostTaskAndReplyWithResult(
197 cache_task_runner_.get(),
198 FROM_HERE,
199 base::Bind(&SimpleCacheLoader::CreateCachePrepDirInPool, cache_path),
200 base::Bind(&SimpleCacheLoader::CreateCachePreppedDir,
201 cache_name,
202 callback,
203 weak_ptr_factory_.GetWeakPtr()));
206 static bool CreateCachePrepDirInPool(const base::FilePath& cache_path) {
207 if (base::PathExists(cache_path))
208 base::DeleteFile(cache_path, /* recursive */ true);
209 return base::CreateDirectory(cache_path);
212 static void CreateCachePreppedDir(const std::string& cache_name,
213 const CacheCallback& callback,
214 base::WeakPtr<SimpleCacheLoader> loader,
215 bool success) {
216 if (!success || !loader) {
217 callback.Run(scoped_refptr<ServiceWorkerCache>());
218 return;
221 callback.Run(loader->CreateServiceWorkerCache(cache_name));
224 void CleanUpDeletedCache(const std::string& cache_name,
225 const BoolCallback& callback) override {
226 DCHECK_CURRENTLY_ON(BrowserThread::IO);
228 // 1. Delete the cache's directory. (CleanUpDeleteCacheDirInPool)
230 base::FilePath cache_path =
231 CreatePersistentCachePath(origin_path_, cache_name);
232 cache_task_runner_->PostTask(
233 FROM_HERE,
234 base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool,
235 cache_path,
236 callback,
237 base::MessageLoopProxy::current()));
240 static void CleanUpDeleteCacheDirInPool(
241 const base::FilePath& cache_path,
242 const BoolCallback& callback,
243 const scoped_refptr<base::MessageLoopProxy>& original_loop) {
244 bool rv = base::DeleteFile(cache_path, true);
245 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv));
248 void WriteIndex(const StringVector& cache_names,
249 const BoolCallback& callback) override {
250 DCHECK_CURRENTLY_ON(BrowserThread::IO);
252 // 1. Create the index file as a string. (WriteIndex)
253 // 2. Write the file to disk. (WriteIndexWriteToFileInPool)
255 ServiceWorkerCacheStorageIndex index;
256 index.set_origin(origin_.spec());
258 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) {
259 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache();
260 index_cache->set_name(cache_names[i]);
263 std::string serialized;
264 bool success = index.SerializeToString(&serialized);
265 DCHECK(success);
267 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp");
268 base::FilePath index_path =
269 origin_path_.AppendASCII(ServiceWorkerCacheStorage::kIndexFileName);
271 cache_task_runner_->PostTask(
272 FROM_HERE,
273 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool,
274 tmp_path,
275 index_path,
276 serialized,
277 callback,
278 base::MessageLoopProxy::current()));
281 static void WriteIndexWriteToFileInPool(
282 const base::FilePath& tmp_path,
283 const base::FilePath& index_path,
284 const std::string& data,
285 const BoolCallback& callback,
286 const scoped_refptr<base::MessageLoopProxy>& original_loop) {
287 int bytes_written = base::WriteFile(tmp_path, data.c_str(), data.size());
288 if (bytes_written != implicit_cast<int>(data.size())) {
289 base::DeleteFile(tmp_path, /* recursive */ false);
290 original_loop->PostTask(FROM_HERE, base::Bind(callback, false));
293 // Atomically rename the temporary index file to become the real one.
294 bool rv = base::ReplaceFile(tmp_path, index_path, NULL);
295 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv));
298 void LoadIndex(scoped_ptr<std::vector<std::string>> names,
299 const StringVectorCallback& callback) override {
300 DCHECK_CURRENTLY_ON(BrowserThread::IO);
302 // 1. Read the file from disk. (LoadIndexReadFileInPool)
303 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile)
305 base::FilePath index_path =
306 origin_path_.AppendASCII(ServiceWorkerCacheStorage::kIndexFileName);
308 cache_task_runner_->PostTask(
309 FROM_HERE,
310 base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool,
311 index_path,
312 base::Passed(names.Pass()),
313 callback,
314 base::MessageLoopProxy::current()));
317 static void LoadIndexReadFileInPool(
318 const base::FilePath& index_path,
319 scoped_ptr<std::vector<std::string> > names,
320 const StringVectorCallback& callback,
321 const scoped_refptr<base::MessageLoopProxy>& original_loop) {
322 std::string body;
323 base::ReadFileToString(index_path, &body);
325 original_loop->PostTask(FROM_HERE,
326 base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile,
327 base::Passed(names.Pass()),
328 callback,
329 body));
332 static void LoadIndexDidReadFile(scoped_ptr<std::vector<std::string> > names,
333 const StringVectorCallback& callback,
334 const std::string& serialized) {
335 DCHECK_CURRENTLY_ON(BrowserThread::IO);
337 ServiceWorkerCacheStorageIndex index;
338 if (index.ParseFromString(serialized)) {
339 for (int i = 0, max = index.cache_size(); i < max; ++i) {
340 const ServiceWorkerCacheStorageIndex::Cache& cache = index.cache(i);
341 names->push_back(cache.name());
345 // TODO(jkarlin): Delete caches that are in the directory and not returned
346 // in LoadIndex.
347 callback.Run(names.Pass());
350 private:
351 ~SimpleCacheLoader() override {}
353 static std::string HexedHash(const std::string& value) {
354 std::string value_hash = base::SHA1HashString(value);
355 std::string valued_hexed_hash = base::StringToLowerASCII(
356 base::HexEncode(value_hash.c_str(), value_hash.length()));
357 return valued_hexed_hash;
360 static base::FilePath CreatePersistentCachePath(
361 const base::FilePath& origin_path,
362 const std::string& cache_name) {
363 return origin_path.AppendASCII(HexedHash(cache_name));
366 const base::FilePath origin_path_;
368 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_;
371 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage(
372 const base::FilePath& path,
373 bool memory_only,
374 base::SequencedTaskRunner* cache_task_runner,
375 net::URLRequestContext* request_context,
376 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
377 base::WeakPtr<storage::BlobStorageContext> blob_context,
378 const GURL& origin)
379 : initialized_(false),
380 origin_path_(path),
381 cache_task_runner_(cache_task_runner),
382 memory_only_(memory_only),
383 weak_factory_(this) {
384 if (memory_only)
385 cache_loader_.reset(new MemoryLoader(cache_task_runner_.get(),
386 request_context,
387 quota_manager_proxy,
388 blob_context,
389 origin));
390 else
391 cache_loader_.reset(new SimpleCacheLoader(origin_path_,
392 cache_task_runner_.get(),
393 request_context,
394 quota_manager_proxy,
395 blob_context,
396 origin));
399 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() {
402 void ServiceWorkerCacheStorage::OpenCache(
403 const std::string& cache_name,
404 const CacheAndErrorCallback& callback) {
405 DCHECK_CURRENTLY_ON(BrowserThread::IO);
407 if (!initialized_) {
408 LazyInit(base::Bind(&ServiceWorkerCacheStorage::OpenCache,
409 weak_factory_.GetWeakPtr(),
410 cache_name,
411 callback));
412 return;
415 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
416 if (cache.get()) {
417 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR);
418 return;
421 cache_loader_->CreateCache(
422 cache_name,
423 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache,
424 weak_factory_.GetWeakPtr(),
425 cache_name,
426 callback));
429 void ServiceWorkerCacheStorage::HasCache(const std::string& cache_name,
430 const BoolAndErrorCallback& callback) {
431 DCHECK_CURRENTLY_ON(BrowserThread::IO);
433 if (!initialized_) {
434 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache,
435 weak_factory_.GetWeakPtr(),
436 cache_name,
437 callback));
438 return;
441 bool has_cache = cache_map_.find(cache_name) != cache_map_.end();
443 callback.Run(has_cache, CACHE_STORAGE_ERROR_NO_ERROR);
446 void ServiceWorkerCacheStorage::DeleteCache(
447 const std::string& cache_name,
448 const BoolAndErrorCallback& callback) {
449 DCHECK_CURRENTLY_ON(BrowserThread::IO);
451 if (!initialized_) {
452 LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache,
453 weak_factory_.GetWeakPtr(),
454 cache_name,
455 callback));
456 return;
459 CacheMap::iterator it = cache_map_.find(cache_name);
460 if (it == cache_map_.end()) {
461 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND);
462 return;
465 base::WeakPtr<ServiceWorkerCache> cache = it->second;
466 cache_map_.erase(it);
468 // Delete the name from ordered_cache_names_.
469 StringVector::iterator iter = std::find(
470 ordered_cache_names_.begin(), ordered_cache_names_.end(), cache_name);
471 DCHECK(iter != ordered_cache_names_.end());
472 ordered_cache_names_.erase(iter);
474 base::Closure closure =
475 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidClose,
476 weak_factory_.GetWeakPtr(), cache_name, callback,
477 ordered_cache_names_, make_scoped_refptr(cache.get()));
479 if (cache) {
480 cache->Close(closure);
481 return;
484 closure.Run();
487 void ServiceWorkerCacheStorage::EnumerateCaches(
488 const StringsAndErrorCallback& callback) {
489 DCHECK_CURRENTLY_ON(BrowserThread::IO);
491 if (!initialized_) {
492 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches,
493 weak_factory_.GetWeakPtr(),
494 callback));
495 return;
498 callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR);
501 void ServiceWorkerCacheStorage::MatchCache(
502 const std::string& cache_name,
503 scoped_ptr<ServiceWorkerFetchRequest> request,
504 const ServiceWorkerCache::ResponseCallback& callback) {
505 DCHECK_CURRENTLY_ON(BrowserThread::IO);
507 if (!initialized_) {
508 LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchCache,
509 weak_factory_.GetWeakPtr(), cache_name,
510 base::Passed(request.Pass()), callback));
511 return;
514 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
516 if (!cache.get()) {
517 callback.Run(ServiceWorkerCache::ErrorTypeNotFound,
518 scoped_ptr<ServiceWorkerResponse>(),
519 scoped_ptr<storage::BlobDataHandle>());
520 return;
523 // Pass the cache along to the callback to keep the cache open until match is
524 // done.
525 cache->Match(request.Pass(),
526 base::Bind(&ServiceWorkerCacheStorage::MatchCacheDidMatch,
527 weak_factory_.GetWeakPtr(), cache, callback));
530 void ServiceWorkerCacheStorage::MatchAllCaches(
531 scoped_ptr<ServiceWorkerFetchRequest> request,
532 const ServiceWorkerCache::ResponseCallback& callback) {
533 DCHECK_CURRENTLY_ON(BrowserThread::IO);
535 if (!initialized_) {
536 LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchAllCaches,
537 weak_factory_.GetWeakPtr(),
538 base::Passed(request.Pass()), callback));
539 return;
542 scoped_ptr<ServiceWorkerCache::ResponseCallback> callback_copy(
543 new ServiceWorkerCache::ResponseCallback(callback));
545 ServiceWorkerCache::ResponseCallback* callback_ptr = callback_copy.get();
546 base::Closure barrier_closure = base::BarrierClosure(
547 ordered_cache_names_.size(),
548 base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatchAll,
549 weak_factory_.GetWeakPtr(),
550 base::Passed(callback_copy.Pass())));
552 for (const std::string& cache_name : ordered_cache_names_) {
553 scoped_refptr<ServiceWorkerCache> cache = GetLoadedCache(cache_name);
554 DCHECK(cache.get());
556 cache->Match(make_scoped_ptr(new ServiceWorkerFetchRequest(*request)),
557 base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatch,
558 weak_factory_.GetWeakPtr(), cache, barrier_closure,
559 callback_ptr));
563 void ServiceWorkerCacheStorage::CloseAllCaches(const base::Closure& callback) {
564 DCHECK_CURRENTLY_ON(BrowserThread::IO);
566 if (!initialized_) {
567 callback.Run();
568 return;
571 int live_cache_count = 0;
572 for (const auto& key_value : cache_map_) {
573 if (key_value.second)
574 live_cache_count += 1;
577 if (live_cache_count == 0) {
578 callback.Run();
579 return;
582 // The closure might modify this object so delay calling it until after
583 // iterating through cache_map_ by adding one to the barrier.
584 base::Closure barrier_closure =
585 base::BarrierClosure(live_cache_count + 1, base::Bind(callback));
587 for (auto& key_value : cache_map_) {
588 if (key_value.second) {
589 key_value.second->Close(base::Bind(
590 CloseAllCachesDidCloseCache,
591 make_scoped_refptr(key_value.second.get()), barrier_closure));
595 barrier_closure.Run();
598 int64 ServiceWorkerCacheStorage::MemoryBackedSize() const {
599 DCHECK_CURRENTLY_ON(BrowserThread::IO);
601 if (!initialized_ || !memory_only_)
602 return 0;
604 int64 sum = 0;
605 for (auto& key_value : cache_map_) {
606 if (key_value.second)
607 sum += key_value.second->MemoryBackedSize();
609 return sum;
612 // Init is run lazily so that it is called on the proper MessageLoop.
613 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) {
614 DCHECK_CURRENTLY_ON(BrowserThread::IO);
615 DCHECK(!initialized_);
617 init_callbacks_.push_back(callback);
619 // If this isn't the first call to LazyInit then return as the initialization
620 // has already started.
621 if (init_callbacks_.size() > 1u)
622 return;
624 // 1. Get the list of cache names (async call)
625 // 2. For each cache name, load the cache (async call)
626 // 3. Once each load is complete, update the map variables.
627 // 4. Call the list of waiting callbacks.
629 scoped_ptr<std::vector<std::string> > indexed_cache_names(
630 new std::vector<std::string>());
632 cache_loader_->LoadIndex(
633 indexed_cache_names.Pass(),
634 base::Bind(&ServiceWorkerCacheStorage::LazyInitDidLoadIndex,
635 weak_factory_.GetWeakPtr(),
636 callback));
639 void ServiceWorkerCacheStorage::LazyInitDidLoadIndex(
640 const base::Closure& callback,
641 scoped_ptr<std::vector<std::string> > indexed_cache_names) {
642 DCHECK_CURRENTLY_ON(BrowserThread::IO);
644 for (size_t i = 0u, max = indexed_cache_names->size(); i < max; ++i) {
645 cache_map_.insert(std::make_pair(indexed_cache_names->at(i),
646 base::WeakPtr<ServiceWorkerCache>()));
647 ordered_cache_names_.push_back(indexed_cache_names->at(i));
650 initialized_ = true;
651 for (std::vector<base::Closure>::iterator it = init_callbacks_.begin();
652 it != init_callbacks_.end();
653 ++it) {
654 it->Run();
656 init_callbacks_.clear();
659 void ServiceWorkerCacheStorage::CreateCacheDidCreateCache(
660 const std::string& cache_name,
661 const CacheAndErrorCallback& callback,
662 const scoped_refptr<ServiceWorkerCache>& cache) {
663 DCHECK_CURRENTLY_ON(BrowserThread::IO);
665 if (!cache.get()) {
666 callback.Run(scoped_refptr<ServiceWorkerCache>(),
667 CACHE_STORAGE_ERROR_CLOSING);
668 return;
671 cache_map_.insert(std::make_pair(cache_name, cache->AsWeakPtr()));
672 ordered_cache_names_.push_back(cache_name);
674 cache_loader_->WriteIndex(
675 ordered_cache_names_,
676 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidWriteIndex,
677 weak_factory_.GetWeakPtr(),
678 callback,
679 cache));
682 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex(
683 const CacheAndErrorCallback& callback,
684 const scoped_refptr<ServiceWorkerCache>& cache,
685 bool success) {
686 DCHECK_CURRENTLY_ON(BrowserThread::IO);
687 DCHECK(cache.get());
689 callback.Run(cache, CACHE_STORAGE_ERROR_NO_ERROR);
692 void ServiceWorkerCacheStorage::DeleteCacheDidClose(
693 const std::string& cache_name,
694 const BoolAndErrorCallback& callback,
695 const StringVector& ordered_cache_names,
696 const scoped_refptr<ServiceWorkerCache>& cache /* might be null */) {
697 cache_loader_->WriteIndex(
698 ordered_cache_names,
699 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex,
700 weak_factory_.GetWeakPtr(), cache_name, callback));
703 void ServiceWorkerCacheStorage::DeleteCacheDidWriteIndex(
704 const std::string& cache_name,
705 const BoolAndErrorCallback& callback,
706 bool success) {
707 DCHECK_CURRENTLY_ON(BrowserThread::IO);
709 cache_loader_->CleanUpDeletedCache(
710 cache_name,
711 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp,
712 weak_factory_.GetWeakPtr(),
713 callback));
716 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp(
717 const BoolAndErrorCallback& callback,
718 bool success) {
719 DCHECK_CURRENTLY_ON(BrowserThread::IO);
721 callback.Run(true, CACHE_STORAGE_ERROR_NO_ERROR);
724 void ServiceWorkerCacheStorage::MatchCacheDidMatch(
725 const scoped_refptr<ServiceWorkerCache>& cache,
726 const ServiceWorkerCache::ResponseCallback& callback,
727 ServiceWorkerCache::ErrorType error,
728 scoped_ptr<ServiceWorkerResponse> response,
729 scoped_ptr<storage::BlobDataHandle> handle) {
730 callback.Run(error, response.Pass(), handle.Pass());
733 void ServiceWorkerCacheStorage::MatchAllCachesDidMatch(
734 scoped_refptr<ServiceWorkerCache> cache,
735 const base::Closure& barrier_closure,
736 ServiceWorkerCache::ResponseCallback* callback,
737 ServiceWorkerCache::ErrorType error,
738 scoped_ptr<ServiceWorkerResponse> response,
739 scoped_ptr<storage::BlobDataHandle> handle) {
740 if (callback->is_null() || error == ServiceWorkerCache::ErrorTypeNotFound) {
741 barrier_closure.Run();
742 return;
744 callback->Run(error, response.Pass(), handle.Pass());
745 callback->Reset(); // Only call the callback once.
747 barrier_closure.Run();
750 void ServiceWorkerCacheStorage::MatchAllCachesDidMatchAll(
751 scoped_ptr<ServiceWorkerCache::ResponseCallback> callback) {
752 if (!callback->is_null()) {
753 callback->Run(ServiceWorkerCache::ErrorTypeNotFound,
754 scoped_ptr<ServiceWorkerResponse>(),
755 scoped_ptr<storage::BlobDataHandle>());
759 scoped_refptr<ServiceWorkerCache> ServiceWorkerCacheStorage::GetLoadedCache(
760 const std::string& cache_name) {
761 DCHECK_CURRENTLY_ON(BrowserThread::IO);
762 DCHECK(initialized_);
764 CacheMap::iterator map_iter = cache_map_.find(cache_name);
765 if (map_iter == cache_map_.end())
766 return scoped_refptr<ServiceWorkerCache>();
768 base::WeakPtr<ServiceWorkerCache> cache = map_iter->second;
770 if (!cache) {
771 scoped_refptr<ServiceWorkerCache> new_cache =
772 cache_loader_->CreateServiceWorkerCache(cache_name);
773 map_iter->second = new_cache->AsWeakPtr();
774 return new_cache;
777 return make_scoped_refptr(cache.get());
780 } // namespace content