Android: Store language .pak files in res/raw rather than assets
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_context_wrapper.cc
blob962da53ee5c8b1c63cf973c9738612e2e4cd81ab
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_utils.h"
28 #include "content/browser/service_worker/service_worker_version.h"
29 #include "content/browser/storage_partition_impl.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 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(),
131 disk_cache_thread,
132 quota_manager_proxy,
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(
142 BrowserThread::IO,
143 FROM_HERE,
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
152 // here.
153 LOG(ERROR) << "ServiceWorkerContextCore is no longer alive.";
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 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(
178 BrowserThread::UI,
179 FROM_HERE,
180 base::Bind(continuation, status == SERVICE_WORKER_OK));
183 void ServiceWorkerContextWrapper::RegisterServiceWorker(
184 const GURL& pattern,
185 const GURL& script_url,
186 const ResultCallback& continuation) {
187 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
188 BrowserThread::PostTask(
189 BrowserThread::IO,
190 FROM_HERE,
191 base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker,
192 this,
193 pattern,
194 script_url,
195 continuation));
196 return;
198 if (!context_core_.get()) {
199 LOG(ERROR) << "ServiceWorkerContextCore is no longer alive.";
200 BrowserThread::PostTask(
201 BrowserThread::IO,
202 FROM_HERE,
203 base::Bind(continuation, false));
204 return;
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(
217 BrowserThread::UI,
218 FROM_HERE,
219 base::Bind(continuation, status == SERVICE_WORKER_OK));
222 void ServiceWorkerContextWrapper::UnregisterServiceWorker(
223 const GURL& pattern,
224 const ResultCallback& continuation) {
225 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
226 BrowserThread::PostTask(
227 BrowserThread::IO,
228 FROM_HERE,
229 base::Bind(&ServiceWorkerContextWrapper::UnregisterServiceWorker,
230 this,
231 pattern,
232 continuation));
233 return;
235 if (!context_core_.get()) {
236 LOG(ERROR) << "ServiceWorkerContextCore is no longer alive.";
237 BrowserThread::PostTask(
238 BrowserThread::IO,
239 FROM_HERE,
240 base::Bind(continuation, false));
241 return;
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,
254 pattern));
255 return;
257 if (!context_core_.get()) {
258 LOG(ERROR) << "ServiceWorkerContextCore is no longer alive.";
259 return;
261 context_core_->storage()->FindRegistrationForPattern(
262 net::SimplifyUrlForRequest(pattern),
263 base::Bind(&ServiceWorkerContextWrapper::DidFindRegistrationForUpdate,
264 this));
267 void ServiceWorkerContextWrapper::StartServiceWorker(
268 const GURL& pattern,
269 const StatusCallback& callback) {
270 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
271 BrowserThread::PostTask(
272 BrowserThread::IO, FROM_HERE,
273 base::Bind(&ServiceWorkerContextWrapper::StartServiceWorker, this,
274 pattern, callback));
275 return;
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));
281 return;
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,
293 version_id));
294 return;
296 if (!context_core_.get()) {
297 LOG(ERROR) << "ServiceWorkerContextCore is no longer alive.";
298 return;
300 ServiceWorkerVersion* version = GetLiveVersion(version_id);
301 if (!version || version->skip_waiting())
302 return;
303 ServiceWorkerRegistration* registration =
304 GetLiveRegistration(version->registration_id());
305 if (!registration || version != registration->waiting_version())
306 return;
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(
322 const GURL& url,
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(
337 BrowserThread::IO,
338 FROM_HERE,
339 base::Bind(callback, std::vector<ServiceWorkerUsageInfo>()));
340 return;
342 context()->storage()->GetAllRegistrationsInfos(base::Bind(
343 &ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins,
344 this, callback));
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));
380 return;
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)
397 return;
398 if (!context_core_.get()) {
399 LOG(ERROR) << "ServiceWorkerContextCore is no longer alive.";
400 return;
402 DCHECK(registration);
403 context_core_->UpdateServiceWorker(registration.get(),
404 true /* force_bypass_cache */);
407 namespace {
408 void StatusCodeToBoolCallbackAdapter(
409 const ServiceWorkerContext::ResultCallback& callback,
410 ServiceWorkerStatusCode code) {
411 callback.Run(code == ServiceWorkerStatusCode::SERVICE_WORKER_OK);
414 void EmptySuccessCallback(bool success) {
416 } // namespace
418 void ServiceWorkerContextWrapper::DeleteForOrigin(
419 const GURL& origin,
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(
425 BrowserThread::IO,
426 FROM_HERE,
427 base::Bind(result, false));
428 return;
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(
439 const GURL& url,
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));
447 return;
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));
453 return;
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);
465 if (!context_core_)
466 return nullptr;
467 return context_core_->GetLiveRegistration(registration_id);
470 ServiceWorkerVersion* ServiceWorkerContextWrapper::GetLiveVersion(
471 int64_t version_id) {
472 DCHECK_CURRENTLY_ON(BrowserThread::IO);
473 if (!context_core_)
474 return nullptr;
475 return context_core_->GetLiveVersion(version_id);
478 std::vector<ServiceWorkerRegistrationInfo>
479 ServiceWorkerContextWrapper::GetAllLiveRegistrationInfo() {
480 DCHECK_CURRENTLY_ON(BrowserThread::IO);
481 if (!context_core_)
482 return std::vector<ServiceWorkerRegistrationInfo>();
483 return context_core_->GetAllLiveRegistrationInfo();
486 std::vector<ServiceWorkerVersionInfo>
487 ServiceWorkerContextWrapper::GetAllLiveVersionInfo() {
488 DCHECK_CURRENTLY_ON(BrowserThread::IO);
489 if (!context_core_)
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);
501 return;
503 context_core_->storage()->FindRegistrationForDocument(
504 net::SimplifyUrlForRequest(document_url), callback);
507 void ServiceWorkerContextWrapper::FindRegistrationForId(
508 int64_t registration_id,
509 const GURL& origin,
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);
515 return;
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>()));
526 return;
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));
538 return;
540 context_core_->storage()->GetUserData(registration_id, key, callback);
543 void ServiceWorkerContextWrapper::StoreRegistrationUserData(
544 int64_t registration_id,
545 const GURL& origin,
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));
552 return;
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));
565 return;
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));
577 return;
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(
600 BrowserThread::IO,
601 FROM_HERE,
602 base::Bind(&ServiceWorkerContextWrapper::InitInternal,
603 this,
604 user_data_directory,
605 base::Passed(&database_task_manager),
606 disk_cache_thread,
607 make_scoped_refptr(quota_manager_proxy),
608 make_scoped_refptr(special_storage_policy)));
609 return;
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(),
621 disk_cache_thread,
622 quota_manager_proxy,
623 special_storage_policy,
624 observer_list_.get(),
625 this));
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();
638 return;
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