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 static void DidFindRegistrationForDocument(
316 const net::CompletionCallback
& callback
,
317 ServiceWorkerStatusCode status
,
318 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
319 int rv
= registration
? net::OK
: net::ERR_CACHE_MISS
;
320 // Use RunSoon here because FindRegistrationForDocument can complete
321 // immediately but CanHandleMainResourceOffline must be async.
322 RunSoon(base::Bind(callback
, rv
));
325 void ServiceWorkerContextWrapper::CanHandleMainResourceOffline(
327 const GURL
& first_party
,
328 const net::CompletionCallback
& callback
) {
329 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
330 context()->storage()->FindRegistrationForDocument(
331 net::SimplifyUrlForRequest(url
),
332 base::Bind(&DidFindRegistrationForDocument
, callback
));
335 void ServiceWorkerContextWrapper::GetAllOriginsInfo(
336 const GetUsageInfoCallback
& callback
) {
337 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
338 if (!context_core_
) {
339 BrowserThread::PostTask(
342 base::Bind(callback
, std::vector
<ServiceWorkerUsageInfo
>()));
345 context()->storage()->GetAllRegistrationsInfos(base::Bind(
346 &ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins
,
350 void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins(
351 const GetUsageInfoCallback
& callback
,
352 const std::vector
<ServiceWorkerRegistrationInfo
>& registrations
) {
353 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
354 std::vector
<ServiceWorkerUsageInfo
> usage_infos
;
356 std::map
<GURL
, ServiceWorkerUsageInfo
> origins
;
357 for (const auto& registration_info
: registrations
) {
358 GURL origin
= registration_info
.pattern
.GetOrigin();
360 ServiceWorkerUsageInfo
& usage_info
= origins
[origin
];
361 if (usage_info
.origin
.is_empty())
362 usage_info
.origin
= origin
;
363 usage_info
.scopes
.push_back(registration_info
.pattern
);
364 usage_info
.total_size_bytes
+= registration_info
.stored_version_size_bytes
;
367 for (const auto& origin_info_pair
: origins
) {
368 usage_infos
.push_back(origin_info_pair
.second
);
370 callback
.Run(usage_infos
);
373 void ServiceWorkerContextWrapper::DidFindRegistrationForCheckHasServiceWorker(
374 const GURL
& other_url
,
375 const CheckHasServiceWorkerCallback
& callback
,
376 ServiceWorkerStatusCode status
,
377 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
378 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
380 if (status
!= SERVICE_WORKER_OK
) {
381 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
382 base::Bind(callback
, false));
386 DCHECK(registration
);
387 BrowserThread::PostTask(
388 BrowserThread::UI
, FROM_HERE
,
389 base::Bind(callback
, registration
->active_version() &&
390 ServiceWorkerUtils::ScopeMatches(
391 registration
->pattern(), other_url
)));
394 void ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin(
395 const GURL
& origin
) {
396 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
397 BrowserThread::PostTask(
398 BrowserThread::IO
, FROM_HERE
,
399 base::Bind(&ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin
,
403 if (!context_core_
.get()) {
406 std::vector
<ServiceWorkerVersionInfo
> live_versions
= GetAllLiveVersionInfo();
407 for (const ServiceWorkerVersionInfo
& info
: live_versions
) {
408 ServiceWorkerVersion
* version
= GetLiveVersion(info
.version_id
);
409 if (version
&& version
->scope().GetOrigin() == origin
)
410 version
->StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
414 void ServiceWorkerContextWrapper::DidFindRegistrationForUpdate(
415 ServiceWorkerStatusCode status
,
416 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
417 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
419 if (status
!= SERVICE_WORKER_OK
)
423 DCHECK(registration
);
424 context_core_
->UpdateServiceWorker(registration
.get(),
425 true /* force_bypass_cache */);
430 void StatusCodeToBoolCallbackAdapter(
431 const ServiceWorkerContext::ResultCallback
& callback
,
432 ServiceWorkerStatusCode code
) {
433 callback
.Run(code
== ServiceWorkerStatusCode::SERVICE_WORKER_OK
);
438 void ServiceWorkerContextWrapper::DeleteForOrigin(
440 const ResultCallback
& result
) {
441 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
442 BrowserThread::PostTask(
443 BrowserThread::IO
, FROM_HERE
,
444 base::Bind(&ServiceWorkerContextWrapper::DeleteForOrigin
, this, origin
,
448 if (!context_core_
) {
449 BrowserThread::PostTask(
452 base::Bind(result
, false));
455 context()->UnregisterServiceWorkers(
456 origin
.GetOrigin(), base::Bind(&StatusCodeToBoolCallbackAdapter
, result
));
459 void ServiceWorkerContextWrapper::CheckHasServiceWorker(
461 const GURL
& other_url
,
462 const CheckHasServiceWorkerCallback
& callback
) {
463 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
464 BrowserThread::PostTask(
465 BrowserThread::IO
, FROM_HERE
,
466 base::Bind(&ServiceWorkerContextWrapper::CheckHasServiceWorker
, this,
467 url
, other_url
, callback
));
470 if (!context_core_
) {
471 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
472 base::Bind(callback
, false));
475 context()->storage()->FindRegistrationForDocument(
476 net::SimplifyUrlForRequest(url
),
477 base::Bind(&ServiceWorkerContextWrapper::
478 DidFindRegistrationForCheckHasServiceWorker
,
479 this, net::SimplifyUrlForRequest(other_url
), callback
));
482 void ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest(
483 const base::Closure
& callback
) {
484 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
485 BrowserThread::PostTask(
486 BrowserThread::IO
, FROM_HERE
,
487 base::Bind(&ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest
,
491 if (!context_core_
) {
492 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, callback
);
495 context_core_
->ClearAllServiceWorkersForTest(callback
);
498 ServiceWorkerRegistration
* ServiceWorkerContextWrapper::GetLiveRegistration(
499 int64_t registration_id
) {
500 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
503 return context_core_
->GetLiveRegistration(registration_id
);
506 ServiceWorkerVersion
* ServiceWorkerContextWrapper::GetLiveVersion(
507 int64_t version_id
) {
508 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
511 return context_core_
->GetLiveVersion(version_id
);
514 std::vector
<ServiceWorkerRegistrationInfo
>
515 ServiceWorkerContextWrapper::GetAllLiveRegistrationInfo() {
516 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
518 return std::vector
<ServiceWorkerRegistrationInfo
>();
519 return context_core_
->GetAllLiveRegistrationInfo();
522 std::vector
<ServiceWorkerVersionInfo
>
523 ServiceWorkerContextWrapper::GetAllLiveVersionInfo() {
524 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
526 return std::vector
<ServiceWorkerVersionInfo
>();
527 return context_core_
->GetAllLiveVersionInfo();
530 void ServiceWorkerContextWrapper::FindRegistrationForDocument(
531 const GURL
& document_url
,
532 const FindRegistrationCallback
& callback
) {
533 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
534 if (!context_core_
) {
535 // FindRegistrationForDocument() can run the callback synchronously.
536 callback
.Run(SERVICE_WORKER_ERROR_ABORT
, nullptr);
539 context_core_
->storage()->FindRegistrationForDocument(
540 net::SimplifyUrlForRequest(document_url
), callback
);
543 void ServiceWorkerContextWrapper::FindRegistrationForId(
544 int64_t registration_id
,
546 const FindRegistrationCallback
& callback
) {
547 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
548 if (!context_core_
) {
549 // FindRegistrationForId() can run the callback synchronously.
550 callback
.Run(SERVICE_WORKER_ERROR_ABORT
, nullptr);
553 context_core_
->storage()->FindRegistrationForId(registration_id
,
554 origin
.GetOrigin(), callback
);
557 void ServiceWorkerContextWrapper::GetAllRegistrations(
558 const GetRegistrationsInfosCallback
& callback
) {
559 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
560 if (!context_core_
) {
561 RunSoon(base::Bind(callback
, std::vector
<ServiceWorkerRegistrationInfo
>()));
564 context_core_
->storage()->GetAllRegistrationsInfos(callback
);
567 void ServiceWorkerContextWrapper::GetRegistrationUserData(
568 int64_t registration_id
,
569 const std::string
& key
,
570 const GetUserDataCallback
& callback
) {
571 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
572 if (!context_core_
) {
573 RunSoon(base::Bind(callback
, std::string(), SERVICE_WORKER_ERROR_ABORT
));
576 context_core_
->storage()->GetUserData(registration_id
, key
, callback
);
579 void ServiceWorkerContextWrapper::StoreRegistrationUserData(
580 int64_t registration_id
,
582 const std::string
& key
,
583 const std::string
& data
,
584 const StatusCallback
& callback
) {
585 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
586 if (!context_core_
) {
587 RunSoon(base::Bind(callback
, SERVICE_WORKER_ERROR_ABORT
));
590 context_core_
->storage()->StoreUserData(registration_id
, origin
.GetOrigin(),
591 key
, data
, callback
);
594 void ServiceWorkerContextWrapper::ClearRegistrationUserData(
595 int64_t registration_id
,
596 const std::string
& key
,
597 const StatusCallback
& callback
) {
598 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
599 if (!context_core_
) {
600 RunSoon(base::Bind(callback
, SERVICE_WORKER_ERROR_ABORT
));
603 context_core_
->storage()->ClearUserData(registration_id
, key
, callback
);
606 void ServiceWorkerContextWrapper::GetUserDataForAllRegistrations(
607 const std::string
& key
,
608 const GetUserDataForAllRegistrationsCallback
& callback
) {
609 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
610 if (!context_core_
) {
611 RunSoon(base::Bind(callback
, std::vector
<std::pair
<int64_t, std::string
>>(),
612 SERVICE_WORKER_ERROR_ABORT
));
615 context_core_
->storage()->GetUserDataForAllRegistrations(key
, callback
);
618 void ServiceWorkerContextWrapper::AddObserver(
619 ServiceWorkerContextObserver
* observer
) {
620 observer_list_
->AddObserver(observer
);
623 void ServiceWorkerContextWrapper::RemoveObserver(
624 ServiceWorkerContextObserver
* observer
) {
625 observer_list_
->RemoveObserver(observer
);
628 void ServiceWorkerContextWrapper::InitInternal(
629 const base::FilePath
& user_data_directory
,
630 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager
,
631 const scoped_refptr
<base::SingleThreadTaskRunner
>& disk_cache_thread
,
632 storage::QuotaManagerProxy
* quota_manager_proxy
,
633 storage::SpecialStoragePolicy
* special_storage_policy
) {
634 if (!BrowserThread::CurrentlyOn(BrowserThread::IO
)) {
635 BrowserThread::PostTask(
638 base::Bind(&ServiceWorkerContextWrapper::InitInternal
,
641 base::Passed(&database_task_manager
),
643 make_scoped_refptr(quota_manager_proxy
),
644 make_scoped_refptr(special_storage_policy
)));
647 // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed.
648 tracked_objects::ScopedTracker
tracking_profile(
649 FROM_HERE_WITH_EXPLICIT_FUNCTION(
650 "477117 ServiceWorkerContextWrapper::InitInternal"));
651 DCHECK(!context_core_
);
652 if (quota_manager_proxy
) {
653 quota_manager_proxy
->RegisterClient(new ServiceWorkerQuotaClient(this));
655 context_core_
.reset(new ServiceWorkerContextCore(user_data_directory
,
656 database_task_manager
.Pass(),
659 special_storage_policy
,
660 observer_list_
.get(),
664 void ServiceWorkerContextWrapper::ShutdownOnIO() {
665 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
666 resource_context_
= nullptr;
667 context_core_
.reset();
670 void ServiceWorkerContextWrapper::DidDeleteAndStartOver(
671 ServiceWorkerStatusCode status
) {
672 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
673 if (status
!= SERVICE_WORKER_OK
) {
674 context_core_
.reset();
677 context_core_
.reset(new ServiceWorkerContextCore(context_core_
.get(), this));
678 DVLOG(1) << "Restarted ServiceWorkerContextCore successfully.";
680 observer_list_
->Notify(FROM_HERE
,
681 &ServiceWorkerContextObserver::OnStorageWiped
);
684 ServiceWorkerContextCore
* ServiceWorkerContextWrapper::context() {
685 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
686 return context_core_
.get();
689 } // namespace content