1 // Copyright 2014 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/child/service_worker/service_worker_provider_context.h"
7 #include "base/thread_task_runner_handle.h"
8 #include "content/child/child_thread_impl.h"
9 #include "content/child/service_worker/service_worker_dispatcher.h"
10 #include "content/child/service_worker/service_worker_handle_reference.h"
11 #include "content/child/service_worker/service_worker_registration_handle_reference.h"
12 #include "content/child/thread_safe_sender.h"
13 #include "content/child/worker_task_runner.h"
17 ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id
)
18 : provider_id_(provider_id
),
19 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
20 if (!ChildThreadImpl::current())
21 return; // May be null in some tests.
22 thread_safe_sender_
= ChildThreadImpl::current()->thread_safe_sender();
23 ServiceWorkerDispatcher
* dispatcher
=
24 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
25 thread_safe_sender_
.get(), main_thread_task_runner_
.get());
27 dispatcher
->AddProviderContext(this);
30 ServiceWorkerProviderContext::~ServiceWorkerProviderContext() {
31 if (ServiceWorkerDispatcher
* dispatcher
=
32 ServiceWorkerDispatcher::GetThreadSpecificInstance()) {
33 // Remove this context from the dispatcher living on the main thread.
34 dispatcher
->RemoveProviderContext(this);
38 ServiceWorkerHandleReference
* ServiceWorkerProviderContext::controller() {
39 DCHECK(main_thread_task_runner_
->RunsTasksOnCurrentThread());
40 return controller_
.get();
43 bool ServiceWorkerProviderContext::GetRegistrationInfoAndVersionAttributes(
44 ServiceWorkerRegistrationObjectInfo
* info
,
45 ServiceWorkerVersionAttributes
* attrs
) {
46 DCHECK(!main_thread_task_runner_
->RunsTasksOnCurrentThread());
47 base::AutoLock
lock(lock_
);
51 *info
= registration_
->info();
53 attrs
->installing
= installing_
->info();
55 attrs
->waiting
= waiting_
->info();
57 attrs
->active
= active_
->info();
61 void ServiceWorkerProviderContext::OnAssociateRegistration(
62 const ServiceWorkerRegistrationObjectInfo
& info
,
63 const ServiceWorkerVersionAttributes
& attrs
) {
64 base::AutoLock
lock(lock_
);
65 DCHECK(main_thread_task_runner_
->RunsTasksOnCurrentThread());
66 DCHECK(!registration_
);
67 DCHECK_NE(kInvalidServiceWorkerRegistrationId
, info
.registration_id
);
68 DCHECK_NE(kInvalidServiceWorkerRegistrationHandleId
, info
.handle_id
);
70 registration_
= ServiceWorkerRegistrationHandleReference::Adopt(
71 info
, thread_safe_sender_
.get());
72 installing_
= ServiceWorkerHandleReference::Adopt(
73 attrs
.installing
, thread_safe_sender_
.get());
74 waiting_
= ServiceWorkerHandleReference::Adopt(
75 attrs
.waiting
, thread_safe_sender_
.get());
76 active_
= ServiceWorkerHandleReference::Adopt(
77 attrs
.active
, thread_safe_sender_
.get());
80 void ServiceWorkerProviderContext::OnDisassociateRegistration() {
81 base::AutoLock
lock(lock_
);
82 DCHECK(main_thread_task_runner_
->RunsTasksOnCurrentThread());
88 registration_
.reset();
91 void ServiceWorkerProviderContext::OnSetControllerServiceWorker(
92 const ServiceWorkerObjectInfo
& info
) {
93 DCHECK(main_thread_task_runner_
->RunsTasksOnCurrentThread());
94 DCHECK(registration_
);
96 // This context is is the primary owner of this handle, keeps the
97 // initial reference until it goes away.
99 ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get());
101 // TODO(kinuko): We can forward the message to other threads here
102 // when we support navigator.serviceWorker in dedicated workers.
105 void ServiceWorkerProviderContext::DestructOnMainThread() const {
106 if (!main_thread_task_runner_
->RunsTasksOnCurrentThread() &&
107 main_thread_task_runner_
->DeleteSoon(FROM_HERE
, this)) {
113 } // namespace content