Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_context_wrapper.cc
blob76986889bd8fef1c2585991d30a8bbba3263e4ec
1 // Copyright 2013 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_context_wrapper.h"
7 #include <map>
8 #include <set>
9 #include <string>
10 #include <vector>
12 #include "base/barrier_closure.h"
13 #include "base/bind.h"
14 #include "base/files/file_path.h"
15 #include "base/lazy_instance.h"
16 #include "base/location.h"
17 #include "base/logging.h"
18 #include "base/profiler/scoped_tracker.h"
19 #include "base/single_thread_task_runner.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "base/threading/sequenced_worker_pool.h"
22 #include "content/browser/service_worker/service_worker_context_core.h"
23 #include "content/browser/service_worker/service_worker_context_observer.h"
24 #include "content/browser/service_worker/service_worker_process_manager.h"
25 #include "content/browser/service_worker/service_worker_quota_client.h"
26 #include "content/browser/service_worker/service_worker_request_handler.h"
27 #include "content/browser/service_worker/service_worker_version.h"
28 #include "content/browser/storage_partition_impl.h"
29 #include "content/common/service_worker/service_worker_utils.h"
30 #include "content/public/browser/browser_context.h"
31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/service_worker_context.h"
33 #include "net/base/net_errors.h"
34 #include "net/base/net_util.h"
35 #include "storage/browser/quota/quota_manager_proxy.h"
36 #include "storage/browser/quota/special_storage_policy.h"
38 namespace content {
40 namespace {
42 typedef std::set<std::string> HeaderNameSet;
43 base::LazyInstance<HeaderNameSet> g_excluded_header_name_set =
44 LAZY_INSTANCE_INITIALIZER;
46 void RunSoon(const base::Closure& closure) {
47 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure);
50 void WorkerStarted(const ServiceWorkerContextWrapper::StatusCallback& callback,
51 ServiceWorkerStatusCode status) {
52 DCHECK_CURRENTLY_ON(BrowserThread::IO);
53 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
54 base::Bind(callback, status));
57 void StartActiveWorkerOnIO(
58 const ServiceWorkerContextWrapper::StatusCallback& callback,
59 ServiceWorkerStatusCode status,
60 const scoped_refptr<ServiceWorkerRegistration>& registration) {
61 DCHECK_CURRENTLY_ON(BrowserThread::IO);
62 if (status == SERVICE_WORKER_OK) {
63 // Pass the reference of |registration| to WorkerStarted callback to prevent
64 // it from being deleted while starting the worker. If the refcount of
65 // |registration| is 1, it will be deleted after WorkerStarted is called.
66 registration->active_version()->StartWorker(
67 base::Bind(WorkerStarted, callback));
68 return;
70 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
71 base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND));
74 } // namespace
76 void ServiceWorkerContext::AddExcludedHeadersForFetchEvent(
77 const std::set<std::string>& header_names) {
78 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
79 tracked_objects::ScopedTracker tracking_profile(
80 FROM_HERE_WITH_EXPLICIT_FUNCTION(
81 "477117 ServiceWorkerContext::AddExcludedHeadersForFetchEvent"));
82 DCHECK_CURRENTLY_ON(BrowserThread::IO);
83 g_excluded_header_name_set.Get().insert(header_names.begin(),
84 header_names.end());
87 bool ServiceWorkerContext::IsExcludedHeaderNameForFetchEvent(
88 const std::string& header_name) {
89 DCHECK_CURRENTLY_ON(BrowserThread::IO);
90 return g_excluded_header_name_set.Get().find(header_name) !=
91 g_excluded_header_name_set.Get().end();
94 ServiceWorkerContext* ServiceWorkerContext::GetServiceWorkerContext(
95 net::URLRequest* request) {
96 DCHECK_CURRENTLY_ON(BrowserThread::IO);
97 ServiceWorkerRequestHandler* handler =
98 ServiceWorkerRequestHandler::GetHandler(request);
99 if (!handler || !handler->context())
100 return nullptr;
101 return handler->context()->wrapper_;
104 ServiceWorkerContextWrapper::ServiceWorkerContextWrapper(
105 BrowserContext* browser_context)
106 : observer_list_(
107 new base::ObserverListThreadSafe<ServiceWorkerContextObserver>()),
108 process_manager_(new ServiceWorkerProcessManager(browser_context)),
109 is_incognito_(false),
110 storage_partition_(nullptr),
111 resource_context_(nullptr) {
112 DCHECK_CURRENTLY_ON(BrowserThread::UI);
115 ServiceWorkerContextWrapper::~ServiceWorkerContextWrapper() {
118 void ServiceWorkerContextWrapper::Init(
119 const base::FilePath& user_data_directory,
120 storage::QuotaManagerProxy* quota_manager_proxy,
121 storage::SpecialStoragePolicy* special_storage_policy) {
122 DCHECK_CURRENTLY_ON(BrowserThread::UI);
124 is_incognito_ = user_data_directory.empty();
125 base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
126 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
127 new ServiceWorkerDatabaseTaskManagerImpl(pool));
128 scoped_refptr<base::SingleThreadTaskRunner> disk_cache_thread =
129 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE);
130 InitInternal(user_data_directory,
131 database_task_manager.Pass(),
132 disk_cache_thread,
133 quota_manager_proxy,
134 special_storage_policy);
137 void ServiceWorkerContextWrapper::Shutdown() {
138 DCHECK_CURRENTLY_ON(BrowserThread::UI);
140 storage_partition_ = nullptr;
141 process_manager_->Shutdown();
142 BrowserThread::PostTask(
143 BrowserThread::IO,
144 FROM_HERE,
145 base::Bind(&ServiceWorkerContextWrapper::ShutdownOnIO, this));
148 void ServiceWorkerContextWrapper::DeleteAndStartOver() {
149 DCHECK_CURRENTLY_ON(BrowserThread::IO);
150 if (!context_core_) {
151 // The context could be null due to system shutdown or restart failure. In
152 // either case, we should not have to recover the system, so just return
153 // here.
154 return;
156 context_core_->DeleteAndStartOver(
157 base::Bind(&ServiceWorkerContextWrapper::DidDeleteAndStartOver, this));
160 StoragePartitionImpl* ServiceWorkerContextWrapper::storage_partition() const {
161 DCHECK_CURRENTLY_ON(BrowserThread::UI);
162 return storage_partition_;
165 void ServiceWorkerContextWrapper::set_storage_partition(
166 StoragePartitionImpl* storage_partition) {
167 DCHECK_CURRENTLY_ON(BrowserThread::UI);
168 storage_partition_ = storage_partition;
171 ResourceContext* ServiceWorkerContextWrapper::resource_context() {
172 DCHECK_CURRENTLY_ON(BrowserThread::IO);
173 return resource_context_;
176 void ServiceWorkerContextWrapper::set_resource_context(
177 ResourceContext* resource_context) {
178 DCHECK_CURRENTLY_ON(BrowserThread::IO);
179 resource_context_ = resource_context;
182 static void FinishRegistrationOnIO(
183 const ServiceWorkerContext::ResultCallback& continuation,
184 ServiceWorkerStatusCode status,
185 const std::string& status_message,
186 int64 registration_id) {
187 DCHECK_CURRENTLY_ON(BrowserThread::IO);
188 BrowserThread::PostTask(
189 BrowserThread::UI,
190 FROM_HERE,
191 base::Bind(continuation, status == SERVICE_WORKER_OK));
194 void ServiceWorkerContextWrapper::RegisterServiceWorker(
195 const GURL& pattern,
196 const GURL& script_url,
197 const ResultCallback& continuation) {
198 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
199 BrowserThread::PostTask(
200 BrowserThread::IO,
201 FROM_HERE,
202 base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker,
203 this,
204 pattern,
205 script_url,
206 continuation));
207 return;
209 if (!context_core_) {
210 BrowserThread::PostTask(
211 BrowserThread::IO,
212 FROM_HERE,
213 base::Bind(continuation, false));
214 return;
216 context()->RegisterServiceWorker(
217 net::SimplifyUrlForRequest(pattern),
218 net::SimplifyUrlForRequest(script_url), NULL /* provider_host */,
219 base::Bind(&FinishRegistrationOnIO, continuation));
222 static void FinishUnregistrationOnIO(
223 const ServiceWorkerContext::ResultCallback& continuation,
224 ServiceWorkerStatusCode status) {
225 DCHECK_CURRENTLY_ON(BrowserThread::IO);
226 BrowserThread::PostTask(
227 BrowserThread::UI,
228 FROM_HERE,
229 base::Bind(continuation, status == SERVICE_WORKER_OK));
232 void ServiceWorkerContextWrapper::UnregisterServiceWorker(
233 const GURL& pattern,
234 const ResultCallback& continuation) {
235 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
236 BrowserThread::PostTask(
237 BrowserThread::IO,
238 FROM_HERE,
239 base::Bind(&ServiceWorkerContextWrapper::UnregisterServiceWorker,
240 this,
241 pattern,
242 continuation));
243 return;
245 if (!context_core_) {
246 BrowserThread::PostTask(
247 BrowserThread::IO,
248 FROM_HERE,
249 base::Bind(continuation, false));
250 return;
253 context()->UnregisterServiceWorker(
254 net::SimplifyUrlForRequest(pattern),
255 base::Bind(&FinishUnregistrationOnIO, continuation));
258 void ServiceWorkerContextWrapper::UpdateRegistration(const GURL& pattern) {
259 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
260 BrowserThread::PostTask(
261 BrowserThread::IO, FROM_HERE,
262 base::Bind(&ServiceWorkerContextWrapper::UpdateRegistration, this,
263 pattern));
264 return;
266 if (!context_core_)
267 return;
268 context_core_->storage()->FindRegistrationForPattern(
269 net::SimplifyUrlForRequest(pattern),
270 base::Bind(&ServiceWorkerContextWrapper::DidFindRegistrationForUpdate,
271 this));
274 void ServiceWorkerContextWrapper::StartServiceWorker(
275 const GURL& pattern,
276 const StatusCallback& callback) {
277 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
278 BrowserThread::PostTask(
279 BrowserThread::IO, FROM_HERE,
280 base::Bind(&ServiceWorkerContextWrapper::StartServiceWorker, this,
281 pattern, callback));
282 return;
284 if (!context_core_) {
285 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
286 base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
287 return;
289 context_core_->storage()->FindRegistrationForPattern(
290 net::SimplifyUrlForRequest(pattern),
291 base::Bind(&StartActiveWorkerOnIO, callback));
294 void ServiceWorkerContextWrapper::SimulateSkipWaiting(int64_t version_id) {
295 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
296 BrowserThread::PostTask(
297 BrowserThread::IO, FROM_HERE,
298 base::Bind(&ServiceWorkerContextWrapper::SimulateSkipWaiting, this,
299 version_id));
300 return;
302 if (!context_core_)
303 return;
304 ServiceWorkerVersion* version = GetLiveVersion(version_id);
305 if (!version || version->skip_waiting())
306 return;
307 ServiceWorkerRegistration* registration =
308 GetLiveRegistration(version->registration_id());
309 if (!registration || version != registration->waiting_version())
310 return;
311 version->set_skip_waiting(true);
312 registration->ActivateWaitingVersionWhenReady();
315 void ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad(
316 int64_t registration_id,
317 bool force_update_on_page_load) {
318 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
319 BrowserThread::PostTask(
320 BrowserThread::IO, FROM_HERE,
321 base::Bind(&ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad, this,
322 registration_id, force_update_on_page_load));
323 return;
325 if (!context_core_)
326 return;
327 context_core_->SetForceUpdateOnPageLoad(registration_id,
328 force_update_on_page_load);
331 static void DidFindRegistrationForDocument(
332 const net::CompletionCallback& callback,
333 ServiceWorkerStatusCode status,
334 const scoped_refptr<ServiceWorkerRegistration>& registration) {
335 int rv = registration ? net::OK : net::ERR_CACHE_MISS;
336 // Use RunSoon here because FindRegistrationForDocument can complete
337 // immediately but CanHandleMainResourceOffline must be async.
338 RunSoon(base::Bind(callback, rv));
341 void ServiceWorkerContextWrapper::CanHandleMainResourceOffline(
342 const GURL& url,
343 const GURL& first_party,
344 const net::CompletionCallback& callback) {
345 DCHECK_CURRENTLY_ON(BrowserThread::IO);
346 context()->storage()->FindRegistrationForDocument(
347 net::SimplifyUrlForRequest(url),
348 base::Bind(&DidFindRegistrationForDocument, callback));
351 void ServiceWorkerContextWrapper::GetAllOriginsInfo(
352 const GetUsageInfoCallback& callback) {
353 DCHECK_CURRENTLY_ON(BrowserThread::IO);
354 if (!context_core_) {
355 BrowserThread::PostTask(
356 BrowserThread::IO,
357 FROM_HERE,
358 base::Bind(callback, std::vector<ServiceWorkerUsageInfo>()));
359 return;
361 context()->storage()->GetAllRegistrationsInfos(base::Bind(
362 &ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins,
363 this, callback));
366 void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins(
367 const GetUsageInfoCallback& callback,
368 const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
369 DCHECK_CURRENTLY_ON(BrowserThread::IO);
370 std::vector<ServiceWorkerUsageInfo> usage_infos;
372 std::map<GURL, ServiceWorkerUsageInfo> origins;
373 for (const auto& registration_info : registrations) {
374 GURL origin = registration_info.pattern.GetOrigin();
376 ServiceWorkerUsageInfo& usage_info = origins[origin];
377 if (usage_info.origin.is_empty())
378 usage_info.origin = origin;
379 usage_info.scopes.push_back(registration_info.pattern);
380 usage_info.total_size_bytes += registration_info.stored_version_size_bytes;
383 for (const auto& origin_info_pair : origins) {
384 usage_infos.push_back(origin_info_pair.second);
386 callback.Run(usage_infos);
389 void ServiceWorkerContextWrapper::DidFindRegistrationForCheckHasServiceWorker(
390 const GURL& other_url,
391 const CheckHasServiceWorkerCallback& callback,
392 ServiceWorkerStatusCode status,
393 const scoped_refptr<ServiceWorkerRegistration>& registration) {
394 DCHECK_CURRENTLY_ON(BrowserThread::IO);
396 if (status != SERVICE_WORKER_OK) {
397 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
398 base::Bind(callback, false));
399 return;
402 DCHECK(registration);
403 BrowserThread::PostTask(
404 BrowserThread::UI, FROM_HERE,
405 base::Bind(callback, registration->active_version() &&
406 ServiceWorkerUtils::ScopeMatches(
407 registration->pattern(), other_url)));
410 void ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin(
411 const GURL& origin) {
412 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
413 BrowserThread::PostTask(
414 BrowserThread::IO, FROM_HERE,
415 base::Bind(&ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin,
416 this, origin));
417 return;
419 if (!context_core_.get()) {
420 return;
422 std::vector<ServiceWorkerVersionInfo> live_versions = GetAllLiveVersionInfo();
423 for (const ServiceWorkerVersionInfo& info : live_versions) {
424 ServiceWorkerVersion* version = GetLiveVersion(info.version_id);
425 if (version && version->scope().GetOrigin() == origin)
426 version->StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
430 void ServiceWorkerContextWrapper::DidFindRegistrationForUpdate(
431 ServiceWorkerStatusCode status,
432 const scoped_refptr<ServiceWorkerRegistration>& registration) {
433 DCHECK_CURRENTLY_ON(BrowserThread::IO);
435 if (status != SERVICE_WORKER_OK)
436 return;
437 if (!context_core_)
438 return;
439 DCHECK(registration);
440 context_core_->UpdateServiceWorker(registration.get(),
441 true /* force_bypass_cache */);
444 namespace {
446 void StatusCodeToBoolCallbackAdapter(
447 const ServiceWorkerContext::ResultCallback& callback,
448 ServiceWorkerStatusCode code) {
449 callback.Run(code == ServiceWorkerStatusCode::SERVICE_WORKER_OK);
452 } // namespace
454 void ServiceWorkerContextWrapper::DeleteForOrigin(
455 const GURL& origin,
456 const ResultCallback& result) {
457 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
458 BrowserThread::PostTask(
459 BrowserThread::IO, FROM_HERE,
460 base::Bind(&ServiceWorkerContextWrapper::DeleteForOrigin, this, origin,
461 result));
462 return;
464 if (!context_core_) {
465 BrowserThread::PostTask(
466 BrowserThread::IO,
467 FROM_HERE,
468 base::Bind(result, false));
469 return;
471 context()->UnregisterServiceWorkers(
472 origin.GetOrigin(), base::Bind(&StatusCodeToBoolCallbackAdapter, result));
475 void ServiceWorkerContextWrapper::CheckHasServiceWorker(
476 const GURL& url,
477 const GURL& other_url,
478 const CheckHasServiceWorkerCallback& callback) {
479 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
480 BrowserThread::PostTask(
481 BrowserThread::IO, FROM_HERE,
482 base::Bind(&ServiceWorkerContextWrapper::CheckHasServiceWorker, this,
483 url, other_url, callback));
484 return;
486 if (!context_core_) {
487 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
488 base::Bind(callback, false));
489 return;
491 context()->storage()->FindRegistrationForDocument(
492 net::SimplifyUrlForRequest(url),
493 base::Bind(&ServiceWorkerContextWrapper::
494 DidFindRegistrationForCheckHasServiceWorker,
495 this, net::SimplifyUrlForRequest(other_url), callback));
498 void ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest(
499 const base::Closure& callback) {
500 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
501 BrowserThread::PostTask(
502 BrowserThread::IO, FROM_HERE,
503 base::Bind(&ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest,
504 this, callback));
505 return;
507 if (!context_core_) {
508 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
509 return;
511 context_core_->ClearAllServiceWorkersForTest(callback);
514 ServiceWorkerRegistration* ServiceWorkerContextWrapper::GetLiveRegistration(
515 int64_t registration_id) {
516 DCHECK_CURRENTLY_ON(BrowserThread::IO);
517 if (!context_core_)
518 return nullptr;
519 return context_core_->GetLiveRegistration(registration_id);
522 ServiceWorkerVersion* ServiceWorkerContextWrapper::GetLiveVersion(
523 int64_t version_id) {
524 DCHECK_CURRENTLY_ON(BrowserThread::IO);
525 if (!context_core_)
526 return nullptr;
527 return context_core_->GetLiveVersion(version_id);
530 std::vector<ServiceWorkerRegistrationInfo>
531 ServiceWorkerContextWrapper::GetAllLiveRegistrationInfo() {
532 DCHECK_CURRENTLY_ON(BrowserThread::IO);
533 if (!context_core_)
534 return std::vector<ServiceWorkerRegistrationInfo>();
535 return context_core_->GetAllLiveRegistrationInfo();
538 std::vector<ServiceWorkerVersionInfo>
539 ServiceWorkerContextWrapper::GetAllLiveVersionInfo() {
540 DCHECK_CURRENTLY_ON(BrowserThread::IO);
541 if (!context_core_)
542 return std::vector<ServiceWorkerVersionInfo>();
543 return context_core_->GetAllLiveVersionInfo();
546 void ServiceWorkerContextWrapper::FindRegistrationForDocument(
547 const GURL& document_url,
548 const FindRegistrationCallback& callback) {
549 DCHECK_CURRENTLY_ON(BrowserThread::IO);
550 if (!context_core_) {
551 // FindRegistrationForDocument() can run the callback synchronously.
552 callback.Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
553 return;
555 context_core_->storage()->FindRegistrationForDocument(
556 net::SimplifyUrlForRequest(document_url), callback);
559 void ServiceWorkerContextWrapper::FindRegistrationForId(
560 int64_t registration_id,
561 const GURL& origin,
562 const FindRegistrationCallback& callback) {
563 DCHECK_CURRENTLY_ON(BrowserThread::IO);
564 if (!context_core_) {
565 // FindRegistrationForId() can run the callback synchronously.
566 callback.Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
567 return;
569 context_core_->storage()->FindRegistrationForId(registration_id,
570 origin.GetOrigin(), callback);
573 void ServiceWorkerContextWrapper::GetAllRegistrations(
574 const GetRegistrationsInfosCallback& callback) {
575 DCHECK_CURRENTLY_ON(BrowserThread::IO);
576 if (!context_core_) {
577 RunSoon(base::Bind(callback, std::vector<ServiceWorkerRegistrationInfo>()));
578 return;
580 context_core_->storage()->GetAllRegistrationsInfos(callback);
583 void ServiceWorkerContextWrapper::GetRegistrationUserData(
584 int64_t registration_id,
585 const std::string& key,
586 const GetUserDataCallback& callback) {
587 DCHECK_CURRENTLY_ON(BrowserThread::IO);
588 if (!context_core_) {
589 RunSoon(base::Bind(callback, std::string(), SERVICE_WORKER_ERROR_ABORT));
590 return;
592 context_core_->storage()->GetUserData(registration_id, key, callback);
595 void ServiceWorkerContextWrapper::StoreRegistrationUserData(
596 int64_t registration_id,
597 const GURL& origin,
598 const std::string& key,
599 const std::string& data,
600 const StatusCallback& callback) {
601 DCHECK_CURRENTLY_ON(BrowserThread::IO);
602 if (!context_core_) {
603 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
604 return;
606 context_core_->storage()->StoreUserData(registration_id, origin.GetOrigin(),
607 key, data, callback);
610 void ServiceWorkerContextWrapper::ClearRegistrationUserData(
611 int64_t registration_id,
612 const std::string& key,
613 const StatusCallback& callback) {
614 DCHECK_CURRENTLY_ON(BrowserThread::IO);
615 if (!context_core_) {
616 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT));
617 return;
619 context_core_->storage()->ClearUserData(registration_id, key, callback);
622 void ServiceWorkerContextWrapper::GetUserDataForAllRegistrations(
623 const std::string& key,
624 const GetUserDataForAllRegistrationsCallback& callback) {
625 DCHECK_CURRENTLY_ON(BrowserThread::IO);
626 if (!context_core_) {
627 RunSoon(base::Bind(callback, std::vector<std::pair<int64_t, std::string>>(),
628 SERVICE_WORKER_ERROR_ABORT));
629 return;
631 context_core_->storage()->GetUserDataForAllRegistrations(key, callback);
634 void ServiceWorkerContextWrapper::AddObserver(
635 ServiceWorkerContextObserver* observer) {
636 observer_list_->AddObserver(observer);
639 void ServiceWorkerContextWrapper::RemoveObserver(
640 ServiceWorkerContextObserver* observer) {
641 observer_list_->RemoveObserver(observer);
644 void ServiceWorkerContextWrapper::InitInternal(
645 const base::FilePath& user_data_directory,
646 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager,
647 const scoped_refptr<base::SingleThreadTaskRunner>& disk_cache_thread,
648 storage::QuotaManagerProxy* quota_manager_proxy,
649 storage::SpecialStoragePolicy* special_storage_policy) {
650 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
651 BrowserThread::PostTask(
652 BrowserThread::IO,
653 FROM_HERE,
654 base::Bind(&ServiceWorkerContextWrapper::InitInternal,
655 this,
656 user_data_directory,
657 base::Passed(&database_task_manager),
658 disk_cache_thread,
659 make_scoped_refptr(quota_manager_proxy),
660 make_scoped_refptr(special_storage_policy)));
661 return;
663 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
664 tracked_objects::ScopedTracker tracking_profile(
665 FROM_HERE_WITH_EXPLICIT_FUNCTION(
666 "477117 ServiceWorkerContextWrapper::InitInternal"));
667 DCHECK(!context_core_);
668 if (quota_manager_proxy) {
669 quota_manager_proxy->RegisterClient(new ServiceWorkerQuotaClient(this));
671 context_core_.reset(new ServiceWorkerContextCore(user_data_directory,
672 database_task_manager.Pass(),
673 disk_cache_thread,
674 quota_manager_proxy,
675 special_storage_policy,
676 observer_list_.get(),
677 this));
680 void ServiceWorkerContextWrapper::ShutdownOnIO() {
681 DCHECK_CURRENTLY_ON(BrowserThread::IO);
682 resource_context_ = nullptr;
683 context_core_.reset();
686 void ServiceWorkerContextWrapper::DidDeleteAndStartOver(
687 ServiceWorkerStatusCode status) {
688 DCHECK_CURRENTLY_ON(BrowserThread::IO);
689 if (status != SERVICE_WORKER_OK) {
690 context_core_.reset();
691 return;
693 context_core_.reset(new ServiceWorkerContextCore(context_core_.get(), this));
694 DVLOG(1) << "Restarted ServiceWorkerContextCore successfully.";
696 observer_list_->Notify(FROM_HERE,
697 &ServiceWorkerContextObserver::OnStorageWiped);
700 ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() {
701 DCHECK_CURRENTLY_ON(BrowserThread::IO);
702 return context_core_.get();
705 } // namespace content