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"
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"
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
));
70 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
71 base::Bind(callback
, SERVICE_WORKER_ERROR_NOT_FOUND
));
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(),
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())
101 return handler
->context()->wrapper_
;
104 ServiceWorkerContextWrapper::ServiceWorkerContextWrapper(
105 BrowserContext
* browser_context
)
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(),
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(
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
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(
191 base::Bind(continuation
, status
== SERVICE_WORKER_OK
));
194 void ServiceWorkerContextWrapper::RegisterServiceWorker(
196 const GURL
& script_url
,
197 const ResultCallback
& continuation
) {
198 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
199 BrowserThread::PostTask(
202 base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker
,
209 if (!context_core_
) {
210 BrowserThread::PostTask(
213 base::Bind(continuation
, false));
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(
229 base::Bind(continuation
, status
== SERVICE_WORKER_OK
));
232 void ServiceWorkerContextWrapper::UnregisterServiceWorker(
234 const ResultCallback
& continuation
) {
235 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
236 BrowserThread::PostTask(
239 base::Bind(&ServiceWorkerContextWrapper::UnregisterServiceWorker
,
245 if (!context_core_
) {
246 BrowserThread::PostTask(
249 base::Bind(continuation
, false));
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,
268 context_core_
->storage()->FindRegistrationForPattern(
269 net::SimplifyUrlForRequest(pattern
),
270 base::Bind(&ServiceWorkerContextWrapper::DidFindRegistrationForUpdate
,
274 void ServiceWorkerContextWrapper::StartServiceWorker(
276 const StatusCallback
& callback
) {
277 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
278 BrowserThread::PostTask(
279 BrowserThread::IO
, FROM_HERE
,
280 base::Bind(&ServiceWorkerContextWrapper::StartServiceWorker
, this,
284 if (!context_core_
) {
285 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
286 base::Bind(callback
, SERVICE_WORKER_ERROR_ABORT
));
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,
304 ServiceWorkerVersion
* version
= GetLiveVersion(version_id
);
305 if (!version
|| version
->skip_waiting())
307 ServiceWorkerRegistration
* registration
=
308 GetLiveRegistration(version
->registration_id());
309 if (!registration
|| version
!= registration
->waiting_version())
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
));
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(
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(
358 base::Bind(callback
, std::vector
<ServiceWorkerUsageInfo
>()));
361 context()->storage()->GetAllRegistrationsInfos(base::Bind(
362 &ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins
,
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));
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
,
419 if (!context_core_
.get()) {
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
)
439 DCHECK(registration
);
440 context_core_
->UpdateServiceWorker(registration
.get(),
441 true /* force_bypass_cache */);
446 void StatusCodeToBoolCallbackAdapter(
447 const ServiceWorkerContext::ResultCallback
& callback
,
448 ServiceWorkerStatusCode code
) {
449 callback
.Run(code
== ServiceWorkerStatusCode::SERVICE_WORKER_OK
);
454 void ServiceWorkerContextWrapper::DeleteForOrigin(
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
,
464 if (!context_core_
) {
465 BrowserThread::PostTask(
468 base::Bind(result
, false));
471 context()->UnregisterServiceWorkers(
472 origin
.GetOrigin(), base::Bind(&StatusCodeToBoolCallbackAdapter
, result
));
475 void ServiceWorkerContextWrapper::CheckHasServiceWorker(
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
));
486 if (!context_core_
) {
487 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
488 base::Bind(callback
, false));
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
,
507 if (!context_core_
) {
508 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, callback
);
511 context_core_
->ClearAllServiceWorkersForTest(callback
);
514 ServiceWorkerRegistration
* ServiceWorkerContextWrapper::GetLiveRegistration(
515 int64_t registration_id
) {
516 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
519 return context_core_
->GetLiveRegistration(registration_id
);
522 ServiceWorkerVersion
* ServiceWorkerContextWrapper::GetLiveVersion(
523 int64_t version_id
) {
524 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
527 return context_core_
->GetLiveVersion(version_id
);
530 std::vector
<ServiceWorkerRegistrationInfo
>
531 ServiceWorkerContextWrapper::GetAllLiveRegistrationInfo() {
532 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
534 return std::vector
<ServiceWorkerRegistrationInfo
>();
535 return context_core_
->GetAllLiveRegistrationInfo();
538 std::vector
<ServiceWorkerVersionInfo
>
539 ServiceWorkerContextWrapper::GetAllLiveVersionInfo() {
540 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
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);
555 context_core_
->storage()->FindRegistrationForDocument(
556 net::SimplifyUrlForRequest(document_url
), callback
);
559 void ServiceWorkerContextWrapper::FindRegistrationForId(
560 int64_t registration_id
,
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);
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
>()));
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
));
592 context_core_
->storage()->GetUserData(registration_id
, key
, callback
);
595 void ServiceWorkerContextWrapper::StoreRegistrationUserData(
596 int64_t registration_id
,
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
));
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
));
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
));
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(
654 base::Bind(&ServiceWorkerContextWrapper::InitInternal
,
657 base::Passed(&database_task_manager
),
659 make_scoped_refptr(quota_manager_proxy
),
660 make_scoped_refptr(special_storage_policy
)));
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(),
675 special_storage_policy
,
676 observer_list_
.get(),
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();
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