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"
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"
29 void CloseAllCachesDidCloseCache(const scoped_refptr
<ServiceWorkerCache
>& cache
,
30 const base::Closure
& barrier_closure
) {
31 barrier_closure
.Run();
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
{
42 typedef base::Callback
<void(const scoped_refptr
<ServiceWorkerCache
>&)>
44 typedef base::Callback
<void(bool)> BoolCallback
;
45 typedef base::Callback
<void(scoped_ptr
<std::vector
<std::string
> >)>
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
,
54 : cache_task_runner_(cache_task_runner
),
55 request_context_(request_context
),
56 quota_manager_proxy_(quota_manager_proxy
),
57 blob_context_(blob_context
),
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;
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_
;
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
98 class ServiceWorkerCacheStorage::MemoryLoader
99 : public ServiceWorkerCacheStorage::CacheLoader
{
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
,
107 : CacheLoader(cache_task_runner
,
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
));
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
);
135 void WriteIndex(const StringVector
& cache_names
,
136 const BoolCallback
& callback
) override
{
140 void LoadIndex(scoped_ptr
<std::vector
<std::string
>> cache_names
,
141 const StringVectorCallback
& callback
) override
{
142 callback
.Run(cache_names
.Pass());
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
152 CacheRefMap cache_refs_
;
155 class ServiceWorkerCacheStorage::SimpleCacheLoader
156 : public ServiceWorkerCacheStorage::CacheLoader
{
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
,
165 : CacheLoader(cache_task_runner
,
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(
179 CreatePersistentCachePath(origin_path_
, cache_name
),
181 quota_manager_proxy_
,
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(),
199 base::Bind(&SimpleCacheLoader::CreateCachePrepDirInPool
, cache_path
),
200 base::Bind(&SimpleCacheLoader::CreateCachePreppedDir
,
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
,
216 if (!success
|| !loader
) {
217 callback
.Run(scoped_refptr
<ServiceWorkerCache
>());
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(
234 base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool
,
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
);
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(
273 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool
,
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(
310 base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool
,
312 base::Passed(names
.Pass()),
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
) {
323 base::ReadFileToString(index_path
, &body
);
325 original_loop
->PostTask(FROM_HERE
,
326 base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile
,
327 base::Passed(names
.Pass()),
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
347 callback
.Run(names
.Pass());
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
,
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
,
379 : initialized_(false),
381 cache_task_runner_(cache_task_runner
),
382 memory_only_(memory_only
),
383 weak_factory_(this) {
385 cache_loader_
.reset(new MemoryLoader(cache_task_runner_
.get(),
391 cache_loader_
.reset(new SimpleCacheLoader(origin_path_
,
392 cache_task_runner_
.get(),
399 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() {
402 void ServiceWorkerCacheStorage::OpenCache(
403 const std::string
& cache_name
,
404 const CacheAndErrorCallback
& callback
) {
405 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
408 LazyInit(base::Bind(&ServiceWorkerCacheStorage::OpenCache
,
409 weak_factory_
.GetWeakPtr(),
415 scoped_refptr
<ServiceWorkerCache
> cache
= GetLoadedCache(cache_name
);
417 callback
.Run(cache
, CACHE_STORAGE_ERROR_NO_ERROR
);
421 cache_loader_
->CreateCache(
423 base::Bind(&ServiceWorkerCacheStorage::CreateCacheDidCreateCache
,
424 weak_factory_
.GetWeakPtr(),
429 void ServiceWorkerCacheStorage::HasCache(const std::string
& cache_name
,
430 const BoolAndErrorCallback
& callback
) {
431 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
434 LazyInit(base::Bind(&ServiceWorkerCacheStorage::HasCache
,
435 weak_factory_
.GetWeakPtr(),
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
);
452 LazyInit(base::Bind(&ServiceWorkerCacheStorage::DeleteCache
,
453 weak_factory_
.GetWeakPtr(),
459 CacheMap::iterator it
= cache_map_
.find(cache_name
);
460 if (it
== cache_map_
.end()) {
461 callback
.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND
);
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()));
480 cache
->Close(closure
);
487 void ServiceWorkerCacheStorage::EnumerateCaches(
488 const StringsAndErrorCallback
& callback
) {
489 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
492 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches
,
493 weak_factory_
.GetWeakPtr(),
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
);
508 LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchCache
,
509 weak_factory_
.GetWeakPtr(), cache_name
,
510 base::Passed(request
.Pass()), callback
));
514 scoped_refptr
<ServiceWorkerCache
> cache
= GetLoadedCache(cache_name
);
517 callback
.Run(ServiceWorkerCache::ErrorTypeNotFound
,
518 scoped_ptr
<ServiceWorkerResponse
>(),
519 scoped_ptr
<storage::BlobDataHandle
>());
523 // Pass the cache along to the callback to keep the cache open until match is
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
);
536 LazyInit(base::Bind(&ServiceWorkerCacheStorage::MatchAllCaches
,
537 weak_factory_
.GetWeakPtr(),
538 base::Passed(request
.Pass()), callback
));
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
);
556 cache
->Match(make_scoped_ptr(new ServiceWorkerFetchRequest(*request
)),
557 base::Bind(&ServiceWorkerCacheStorage::MatchAllCachesDidMatch
,
558 weak_factory_
.GetWeakPtr(), cache
, barrier_closure
,
563 void ServiceWorkerCacheStorage::CloseAllCaches(const base::Closure
& callback
) {
564 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
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) {
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_
)
605 for (auto& key_value
: cache_map_
) {
606 if (key_value
.second
)
607 sum
+= key_value
.second
->MemoryBackedSize();
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)
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(),
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
));
651 for (std::vector
<base::Closure
>::iterator it
= init_callbacks_
.begin();
652 it
!= init_callbacks_
.end();
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
);
666 callback
.Run(scoped_refptr
<ServiceWorkerCache
>(),
667 CACHE_STORAGE_ERROR_CLOSING
);
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(),
682 void ServiceWorkerCacheStorage::CreateCacheDidWriteIndex(
683 const CacheAndErrorCallback
& callback
,
684 const scoped_refptr
<ServiceWorkerCache
>& cache
,
686 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
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(
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
,
707 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
709 cache_loader_
->CleanUpDeletedCache(
711 base::Bind(&ServiceWorkerCacheStorage::DeleteCacheDidCleanUp
,
712 weak_factory_
.GetWeakPtr(),
716 void ServiceWorkerCacheStorage::DeleteCacheDidCleanUp(
717 const BoolAndErrorCallback
& callback
,
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();
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
;
771 scoped_refptr
<ServiceWorkerCache
> new_cache
=
772 cache_loader_
->CreateServiceWorkerCache(cache_name
);
773 map_iter
->second
= new_cache
->AsWeakPtr();
777 return make_scoped_refptr(cache
.get());
780 } // namespace content