Remove the 'gyp_config' concept from MB.
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_context_wrapper.cc
blobc489a77dc04b1b7008ffeb8e6599b40e3f11d5da
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 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(
326 const GURL& url,
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(
340 BrowserThread::IO,
341 FROM_HERE,
342 base::Bind(callback, std::vector<ServiceWorkerUsageInfo>()));
343 return;
345 context()->storage()->GetAllRegistrationsInfos(base::Bind(
346 &ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins,
347 this, callback));
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));
383 return;
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,
400 this, origin));
401 return;
403 if (!context_core_.get()) {
404 return;
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)
420 return;
421 if (!context_core_)
422 return;
423 DCHECK(registration);
424 context_core_->UpdateServiceWorker(registration.get(),
425 true /* force_bypass_cache */);
428 namespace {
430 void StatusCodeToBoolCallbackAdapter(
431 const ServiceWorkerContext::ResultCallback& callback,
432 ServiceWorkerStatusCode code) {
433 callback.Run(code == ServiceWorkerStatusCode::SERVICE_WORKER_OK);
436 } // namespace
438 void ServiceWorkerContextWrapper::DeleteForOrigin(
439 const GURL& origin,
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,
445 result));
446 return;
448 if (!context_core_) {
449 BrowserThread::PostTask(
450 BrowserThread::IO,
451 FROM_HERE,
452 base::Bind(result, false));
453 return;
455 context()->UnregisterServiceWorkers(
456 origin.GetOrigin(), base::Bind(&StatusCodeToBoolCallbackAdapter, result));
459 void ServiceWorkerContextWrapper::CheckHasServiceWorker(
460 const GURL& url,
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));
468 return;
470 if (!context_core_) {
471 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
472 base::Bind(callback, false));
473 return;
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,
488 this, callback));
489 return;
491 if (!context_core_) {
492 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
493 return;
495 context_core_->ClearAllServiceWorkersForTest(callback);
498 ServiceWorkerRegistration* ServiceWorkerContextWrapper::GetLiveRegistration(
499 int64_t registration_id) {
500 DCHECK_CURRENTLY_ON(BrowserThread::IO);
501 if (!context_core_)
502 return nullptr;
503 return context_core_->GetLiveRegistration(registration_id);
506 ServiceWorkerVersion* ServiceWorkerContextWrapper::GetLiveVersion(
507 int64_t version_id) {
508 DCHECK_CURRENTLY_ON(BrowserThread::IO);
509 if (!context_core_)
510 return nullptr;
511 return context_core_->GetLiveVersion(version_id);
514 std::vector<ServiceWorkerRegistrationInfo>
515 ServiceWorkerContextWrapper::GetAllLiveRegistrationInfo() {
516 DCHECK_CURRENTLY_ON(BrowserThread::IO);
517 if (!context_core_)
518 return std::vector<ServiceWorkerRegistrationInfo>();
519 return context_core_->GetAllLiveRegistrationInfo();
522 std::vector<ServiceWorkerVersionInfo>
523 ServiceWorkerContextWrapper::GetAllLiveVersionInfo() {
524 DCHECK_CURRENTLY_ON(BrowserThread::IO);
525 if (!context_core_)
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);
537 return;
539 context_core_->storage()->FindRegistrationForDocument(
540 net::SimplifyUrlForRequest(document_url), callback);
543 void ServiceWorkerContextWrapper::FindRegistrationForId(
544 int64_t registration_id,
545 const GURL& origin,
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);
551 return;
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>()));
562 return;
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));
574 return;
576 context_core_->storage()->GetUserData(registration_id, key, callback);
579 void ServiceWorkerContextWrapper::StoreRegistrationUserData(
580 int64_t registration_id,
581 const GURL& origin,
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));
588 return;
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));
601 return;
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));
613 return;
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(
636 BrowserThread::IO,
637 FROM_HERE,
638 base::Bind(&ServiceWorkerContextWrapper::InitInternal,
639 this,
640 user_data_directory,
641 base::Passed(&database_task_manager),
642 disk_cache_thread,
643 make_scoped_refptr(quota_manager_proxy),
644 make_scoped_refptr(special_storage_policy)));
645 return;
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(),
657 disk_cache_thread,
658 quota_manager_proxy,
659 special_storage_policy,
660 observer_list_.get(),
661 this));
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();
675 return;
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