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 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
114 ServiceWorkerContextWrapper::~ServiceWorkerContextWrapper() {
117 void ServiceWorkerContextWrapper::Init(
118 const base::FilePath
& user_data_directory
,
119 storage::QuotaManagerProxy
* quota_manager_proxy
,
120 storage::SpecialStoragePolicy
* special_storage_policy
) {
121 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
123 is_incognito_
= user_data_directory
.empty();
124 base::SequencedWorkerPool
* pool
= BrowserThread::GetBlockingPool();
125 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
126 new ServiceWorkerDatabaseTaskManagerImpl(pool
));
127 scoped_refptr
<base::SingleThreadTaskRunner
> disk_cache_thread
=
128 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE
);
129 InitInternal(user_data_directory
,
130 database_task_manager
.Pass(),
133 special_storage_policy
);
136 void ServiceWorkerContextWrapper::Shutdown() {
137 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
139 storage_partition_
= nullptr;
140 process_manager_
->Shutdown();
141 BrowserThread::PostTask(
144 base::Bind(&ServiceWorkerContextWrapper::ShutdownOnIO
, this));
147 void ServiceWorkerContextWrapper::DeleteAndStartOver() {
148 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
149 if (!context_core_
) {
150 // The context could be null due to system shutdown or restart failure. In
151 // either case, we should not have to recover the system, so just return
153 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
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 static void FinishRegistrationOnIO(
172 const ServiceWorkerContext::ResultCallback
& continuation
,
173 ServiceWorkerStatusCode status
,
174 const std::string
& status_message
,
175 int64 registration_id
) {
176 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
177 BrowserThread::PostTask(
180 base::Bind(continuation
, status
== SERVICE_WORKER_OK
));
183 void ServiceWorkerContextWrapper::RegisterServiceWorker(
185 const GURL
& script_url
,
186 const ResultCallback
& continuation
) {
187 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
188 BrowserThread::PostTask(
191 base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker
,
198 if (!context_core_
.get()) {
199 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
200 BrowserThread::PostTask(
203 base::Bind(continuation
, false));
206 context()->RegisterServiceWorker(
207 net::SimplifyUrlForRequest(pattern
),
208 net::SimplifyUrlForRequest(script_url
), NULL
/* provider_host */,
209 base::Bind(&FinishRegistrationOnIO
, continuation
));
212 static void FinishUnregistrationOnIO(
213 const ServiceWorkerContext::ResultCallback
& continuation
,
214 ServiceWorkerStatusCode status
) {
215 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
216 BrowserThread::PostTask(
219 base::Bind(continuation
, status
== SERVICE_WORKER_OK
));
222 void ServiceWorkerContextWrapper::UnregisterServiceWorker(
224 const ResultCallback
& continuation
) {
225 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
226 BrowserThread::PostTask(
229 base::Bind(&ServiceWorkerContextWrapper::UnregisterServiceWorker
,
235 if (!context_core_
.get()) {
236 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
237 BrowserThread::PostTask(
240 base::Bind(continuation
, false));
244 context()->UnregisterServiceWorker(
245 net::SimplifyUrlForRequest(pattern
),
246 base::Bind(&FinishUnregistrationOnIO
, continuation
));
249 void ServiceWorkerContextWrapper::UpdateRegistration(const GURL
& pattern
) {
250 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
251 BrowserThread::PostTask(
252 BrowserThread::IO
, FROM_HERE
,
253 base::Bind(&ServiceWorkerContextWrapper::UpdateRegistration
, this,
257 if (!context_core_
.get()) {
258 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
261 context_core_
->storage()->FindRegistrationForPattern(
262 net::SimplifyUrlForRequest(pattern
),
263 base::Bind(&ServiceWorkerContextWrapper::DidFindRegistrationForUpdate
,
267 void ServiceWorkerContextWrapper::StartServiceWorker(
269 const StatusCallback
& callback
) {
270 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
271 BrowserThread::PostTask(
272 BrowserThread::IO
, FROM_HERE
,
273 base::Bind(&ServiceWorkerContextWrapper::StartServiceWorker
, this,
277 if (!context_core_
.get()) {
278 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
279 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
280 base::Bind(callback
, SERVICE_WORKER_ERROR_ABORT
));
283 context_core_
->storage()->FindRegistrationForPattern(
284 net::SimplifyUrlForRequest(pattern
),
285 base::Bind(&StartActiveWorkerOnIO
, callback
));
288 void ServiceWorkerContextWrapper::SimulateSkipWaiting(int64_t version_id
) {
289 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
290 BrowserThread::PostTask(
291 BrowserThread::IO
, FROM_HERE
,
292 base::Bind(&ServiceWorkerContextWrapper::SimulateSkipWaiting
, this,
296 if (!context_core_
.get()) {
297 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
300 ServiceWorkerVersion
* version
= GetLiveVersion(version_id
);
301 if (!version
|| version
->skip_waiting())
303 ServiceWorkerRegistration
* registration
=
304 GetLiveRegistration(version
->registration_id());
305 if (!registration
|| version
!= registration
->waiting_version())
307 version
->set_skip_waiting(true);
308 registration
->ActivateWaitingVersionWhenReady();
311 static void DidFindRegistrationForDocument(
312 const net::CompletionCallback
& callback
,
313 ServiceWorkerStatusCode status
,
314 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
315 int rv
= registration
? net::OK
: net::ERR_CACHE_MISS
;
316 // Use RunSoon here because FindRegistrationForDocument can complete
317 // immediately but CanHandleMainResourceOffline must be async.
318 RunSoon(base::Bind(callback
, rv
));
321 void ServiceWorkerContextWrapper::CanHandleMainResourceOffline(
323 const GURL
& first_party
,
324 const net::CompletionCallback
& callback
) {
325 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
326 context()->storage()->FindRegistrationForDocument(
327 net::SimplifyUrlForRequest(url
),
328 base::Bind(&DidFindRegistrationForDocument
, callback
));
331 void ServiceWorkerContextWrapper::GetAllOriginsInfo(
332 const GetUsageInfoCallback
& callback
) {
333 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
334 if (!context_core_
.get()) {
335 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
336 BrowserThread::PostTask(
339 base::Bind(callback
, std::vector
<ServiceWorkerUsageInfo
>()));
342 context()->storage()->GetAllRegistrationsInfos(base::Bind(
343 &ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins
,
347 void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins(
348 const GetUsageInfoCallback
& callback
,
349 const std::vector
<ServiceWorkerRegistrationInfo
>& registrations
) {
350 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
351 std::vector
<ServiceWorkerUsageInfo
> usage_infos
;
353 std::map
<GURL
, ServiceWorkerUsageInfo
> origins
;
354 for (const auto& registration_info
: registrations
) {
355 GURL origin
= registration_info
.pattern
.GetOrigin();
357 ServiceWorkerUsageInfo
& usage_info
= origins
[origin
];
358 if (usage_info
.origin
.is_empty())
359 usage_info
.origin
= origin
;
360 usage_info
.scopes
.push_back(registration_info
.pattern
);
361 usage_info
.total_size_bytes
+= registration_info
.stored_version_size_bytes
;
364 for (const auto& origin_info_pair
: origins
) {
365 usage_infos
.push_back(origin_info_pair
.second
);
367 callback
.Run(usage_infos
);
370 void ServiceWorkerContextWrapper::DidFindRegistrationForCheckHasServiceWorker(
371 const GURL
& other_url
,
372 const CheckHasServiceWorkerCallback
& callback
,
373 ServiceWorkerStatusCode status
,
374 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
375 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
377 if (status
!= SERVICE_WORKER_OK
) {
378 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
379 base::Bind(callback
, false));
383 DCHECK(registration
);
384 BrowserThread::PostTask(
385 BrowserThread::UI
, FROM_HERE
,
386 base::Bind(callback
, registration
->active_version() &&
387 ServiceWorkerUtils::ScopeMatches(
388 registration
->pattern(), other_url
)));
391 void ServiceWorkerContextWrapper::DidFindRegistrationForUpdate(
392 ServiceWorkerStatusCode status
,
393 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
394 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
396 if (status
!= SERVICE_WORKER_OK
)
398 if (!context_core_
.get()) {
399 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
402 DCHECK(registration
);
403 context_core_
->UpdateServiceWorker(registration
.get(),
404 true /* force_bypass_cache */);
408 void StatusCodeToBoolCallbackAdapter(
409 const ServiceWorkerContext::ResultCallback
& callback
,
410 ServiceWorkerStatusCode code
) {
411 callback
.Run(code
== ServiceWorkerStatusCode::SERVICE_WORKER_OK
);
414 void EmptySuccessCallback(bool success
) {
418 void ServiceWorkerContextWrapper::DeleteForOrigin(
420 const ResultCallback
& result
) {
421 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
422 if (!context_core_
.get()) {
423 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
424 BrowserThread::PostTask(
427 base::Bind(result
, false));
430 context()->UnregisterServiceWorkers(
431 origin
.GetOrigin(), base::Bind(&StatusCodeToBoolCallbackAdapter
, result
));
434 void ServiceWorkerContextWrapper::DeleteForOrigin(const GURL
& origin
) {
435 DeleteForOrigin(origin
, base::Bind(&EmptySuccessCallback
));
438 void ServiceWorkerContextWrapper::CheckHasServiceWorker(
440 const GURL
& other_url
,
441 const CheckHasServiceWorkerCallback
& callback
) {
442 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
443 BrowserThread::PostTask(
444 BrowserThread::IO
, FROM_HERE
,
445 base::Bind(&ServiceWorkerContextWrapper::CheckHasServiceWorker
, this,
446 url
, other_url
, callback
));
449 if (!context_core_
.get()) {
450 LOG(ERROR
) << "ServiceWorkerContextCore is no longer alive.";
451 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
452 base::Bind(callback
, false));
455 context()->storage()->FindRegistrationForDocument(
456 net::SimplifyUrlForRequest(url
),
457 base::Bind(&ServiceWorkerContextWrapper::
458 DidFindRegistrationForCheckHasServiceWorker
,
459 this, net::SimplifyUrlForRequest(other_url
), callback
));
462 ServiceWorkerRegistration
* ServiceWorkerContextWrapper::GetLiveRegistration(
463 int64_t registration_id
) {
464 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
467 return context_core_
->GetLiveRegistration(registration_id
);
470 ServiceWorkerVersion
* ServiceWorkerContextWrapper::GetLiveVersion(
471 int64_t version_id
) {
472 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
475 return context_core_
->GetLiveVersion(version_id
);
478 std::vector
<ServiceWorkerRegistrationInfo
>
479 ServiceWorkerContextWrapper::GetAllLiveRegistrationInfo() {
480 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
482 return std::vector
<ServiceWorkerRegistrationInfo
>();
483 return context_core_
->GetAllLiveRegistrationInfo();
486 std::vector
<ServiceWorkerVersionInfo
>
487 ServiceWorkerContextWrapper::GetAllLiveVersionInfo() {
488 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
490 return std::vector
<ServiceWorkerVersionInfo
>();
491 return context_core_
->GetAllLiveVersionInfo();
494 void ServiceWorkerContextWrapper::FindRegistrationForDocument(
495 const GURL
& document_url
,
496 const FindRegistrationCallback
& callback
) {
497 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
498 if (!context_core_
) {
499 // FindRegistrationForDocument() can run the callback synchronously.
500 callback
.Run(SERVICE_WORKER_ERROR_ABORT
, nullptr);
503 context_core_
->storage()->FindRegistrationForDocument(
504 net::SimplifyUrlForRequest(document_url
), callback
);
507 void ServiceWorkerContextWrapper::FindRegistrationForId(
508 int64_t registration_id
,
510 const FindRegistrationCallback
& callback
) {
511 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
512 if (!context_core_
) {
513 // FindRegistrationForId() can run the callback synchronously.
514 callback
.Run(SERVICE_WORKER_ERROR_ABORT
, nullptr);
517 context_core_
->storage()->FindRegistrationForId(registration_id
,
518 origin
.GetOrigin(), callback
);
521 void ServiceWorkerContextWrapper::GetAllRegistrations(
522 const GetRegistrationsInfosCallback
& callback
) {
523 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
524 if (!context_core_
) {
525 RunSoon(base::Bind(callback
, std::vector
<ServiceWorkerRegistrationInfo
>()));
528 context_core_
->storage()->GetAllRegistrationsInfos(callback
);
531 void ServiceWorkerContextWrapper::GetRegistrationUserData(
532 int64_t registration_id
,
533 const std::string
& key
,
534 const GetUserDataCallback
& callback
) {
535 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
536 if (!context_core_
) {
537 RunSoon(base::Bind(callback
, std::string(), SERVICE_WORKER_ERROR_ABORT
));
540 context_core_
->storage()->GetUserData(registration_id
, key
, callback
);
543 void ServiceWorkerContextWrapper::StoreRegistrationUserData(
544 int64_t registration_id
,
546 const std::string
& key
,
547 const std::string
& data
,
548 const StatusCallback
& callback
) {
549 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
550 if (!context_core_
) {
551 RunSoon(base::Bind(callback
, SERVICE_WORKER_ERROR_ABORT
));
554 context_core_
->storage()->StoreUserData(registration_id
, origin
.GetOrigin(),
555 key
, data
, callback
);
558 void ServiceWorkerContextWrapper::ClearRegistrationUserData(
559 int64_t registration_id
,
560 const std::string
& key
,
561 const StatusCallback
& callback
) {
562 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
563 if (!context_core_
) {
564 RunSoon(base::Bind(callback
, SERVICE_WORKER_ERROR_ABORT
));
567 context_core_
->storage()->ClearUserData(registration_id
, key
, callback
);
570 void ServiceWorkerContextWrapper::GetUserDataForAllRegistrations(
571 const std::string
& key
,
572 const GetUserDataForAllRegistrationsCallback
& callback
) {
573 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
574 if (!context_core_
) {
575 RunSoon(base::Bind(callback
, std::vector
<std::pair
<int64_t, std::string
>>(),
576 SERVICE_WORKER_ERROR_ABORT
));
579 context_core_
->storage()->GetUserDataForAllRegistrations(key
, callback
);
582 void ServiceWorkerContextWrapper::AddObserver(
583 ServiceWorkerContextObserver
* observer
) {
584 observer_list_
->AddObserver(observer
);
587 void ServiceWorkerContextWrapper::RemoveObserver(
588 ServiceWorkerContextObserver
* observer
) {
589 observer_list_
->RemoveObserver(observer
);
592 void ServiceWorkerContextWrapper::InitInternal(
593 const base::FilePath
& user_data_directory
,
594 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
595 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
596 storage::QuotaManagerProxy
* quota_manager_proxy
,
597 storage::SpecialStoragePolicy
* special_storage_policy
) {
598 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
599 BrowserThread::PostTask(
602 base::Bind(&ServiceWorkerContextWrapper::InitInternal
,
605 base::Passed(&database_task_manager
),
607 make_scoped_refptr(quota_manager_proxy
),
608 make_scoped_refptr(special_storage_policy
)));
611 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
612 tracked_objects::ScopedTracker
tracking_profile(
613 FROM_HERE_WITH_EXPLICIT_FUNCTION(
614 "477117 ServiceWorkerContextWrapper::InitInternal"));
615 DCHECK(!context_core_
);
616 if (quota_manager_proxy
) {
617 quota_manager_proxy
->RegisterClient(new ServiceWorkerQuotaClient(this));
619 context_core_
.reset(new ServiceWorkerContextCore(user_data_directory
,
620 database_task_manager
.Pass(),
623 special_storage_policy
,
624 observer_list_
.get(),
628 void ServiceWorkerContextWrapper::ShutdownOnIO() {
629 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
630 context_core_
.reset();
633 void ServiceWorkerContextWrapper::DidDeleteAndStartOver(
634 ServiceWorkerStatusCode status
) {
635 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
636 if (status
!= SERVICE_WORKER_OK
) {
637 context_core_
.reset();
640 context_core_
.reset(new ServiceWorkerContextCore(context_core_
.get(), this));
641 DVLOG(1) << "Restarted ServiceWorkerContextCore successfully.";
643 observer_list_
->Notify(FROM_HERE
,
644 &ServiceWorkerContextObserver::OnStorageWiped
);
647 ServiceWorkerContextCore
* ServiceWorkerContextWrapper::context() {
648 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
649 return context_core_
.get();
652 } // namespace content