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"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/stl_util.h"
10 #include "content/child/child_thread.h"
11 #include "content/child/service_worker/service_worker_dispatcher.h"
12 #include "content/child/service_worker/service_worker_handle_reference.h"
13 #include "content/child/service_worker/service_worker_registration_handle_reference.h"
14 #include "content/child/thread_safe_sender.h"
15 #include "content/child/worker_task_runner.h"
16 #include "content/common/service_worker/service_worker_messages.h"
20 ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id
)
21 : provider_id_(provider_id
),
22 main_thread_loop_proxy_(base::MessageLoopProxy::current()) {
23 if (!ChildThread::current())
24 return; // May be null in some tests.
25 thread_safe_sender_
= ChildThread::current()->thread_safe_sender();
26 ServiceWorkerDispatcher
* dispatcher
=
27 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
28 thread_safe_sender_
.get());
30 dispatcher
->AddProviderContext(this);
33 ServiceWorkerProviderContext::~ServiceWorkerProviderContext() {
34 if (ServiceWorkerDispatcher
* dispatcher
=
35 ServiceWorkerDispatcher::GetThreadSpecificInstance()) {
36 dispatcher
->RemoveProviderContext(this);
40 ServiceWorkerHandleReference
* ServiceWorkerProviderContext::installing() {
41 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
42 return installing_
.get();
45 ServiceWorkerHandleReference
* ServiceWorkerProviderContext::waiting() {
46 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
47 return waiting_
.get();
50 ServiceWorkerHandleReference
* ServiceWorkerProviderContext::active() {
51 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
55 ServiceWorkerHandleReference
* ServiceWorkerProviderContext::controller() {
56 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
57 return controller_
.get();
60 ServiceWorkerRegistrationHandleReference
*
61 ServiceWorkerProviderContext::registration() {
62 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
63 return registration_
.get();
66 ServiceWorkerVersionAttributes
67 ServiceWorkerProviderContext::GetVersionAttributes() {
68 ServiceWorkerVersionAttributes attrs
;
70 attrs
.installing
= installing()->info();
72 attrs
.waiting
= waiting()->info();
74 attrs
.active
= active()->info();
78 void ServiceWorkerProviderContext::OnAssociateRegistration(
79 const ServiceWorkerRegistrationObjectInfo
& info
,
80 const ServiceWorkerVersionAttributes
& attrs
) {
81 DCHECK(!registration_
);
82 DCHECK_NE(kInvalidServiceWorkerRegistrationHandleId
, info
.handle_id
);
83 registration_
= ServiceWorkerRegistrationHandleReference::Adopt(
84 info
, thread_safe_sender_
.get());
85 installing_
= ServiceWorkerHandleReference::Adopt(
86 attrs
.installing
, thread_safe_sender_
.get());
87 waiting_
= ServiceWorkerHandleReference::Adopt(
88 attrs
.waiting
, thread_safe_sender_
.get());
89 active_
= ServiceWorkerHandleReference::Adopt(
90 attrs
.active
, thread_safe_sender_
.get());
93 void ServiceWorkerProviderContext::OnDisassociateRegistration() {
98 registration_
.reset();
101 void ServiceWorkerProviderContext::OnServiceWorkerStateChanged(
103 blink::WebServiceWorkerState state
) {
104 ServiceWorkerHandleReference
* which
= NULL
;
105 if (handle_id
== controller_handle_id())
106 which
= controller_
.get();
107 else if (handle_id
== active_handle_id())
108 which
= active_
.get();
109 else if (handle_id
== waiting_handle_id())
110 which
= waiting_
.get();
111 else if (handle_id
== installing_handle_id())
112 which
= installing_
.get();
114 // We should only get messages for ServiceWorkers associated with
118 which
->set_state(state
);
120 // TODO(kinuko): We can forward the message to other threads here
121 // when we support navigator.serviceWorker in dedicated workers.
124 void ServiceWorkerProviderContext::OnSetInstallingServiceWorker(
125 int registration_handle_id
,
126 const ServiceWorkerObjectInfo
& info
) {
127 DCHECK(IsAssociatedWithRegistration(registration_handle_id
));
129 ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get());
132 void ServiceWorkerProviderContext::OnSetWaitingServiceWorker(
133 int registration_handle_id
,
134 const ServiceWorkerObjectInfo
& info
) {
135 DCHECK(IsAssociatedWithRegistration(registration_handle_id
));
137 ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get());
140 void ServiceWorkerProviderContext::OnSetActiveServiceWorker(
141 int registration_handle_id
,
142 const ServiceWorkerObjectInfo
& info
) {
143 DCHECK(IsAssociatedWithRegistration(registration_handle_id
));
145 ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get());
148 void ServiceWorkerProviderContext::OnSetControllerServiceWorker(
149 int registration_handle_id
,
150 const ServiceWorkerObjectInfo
& info
) {
151 DCHECK(IsAssociatedWithRegistration(registration_handle_id
));
153 // This context is is the primary owner of this handle, keeps the
154 // initial reference until it goes away.
156 ServiceWorkerHandleReference::Adopt(info
, thread_safe_sender_
.get());
158 // TODO(kinuko): We can forward the message to other threads here
159 // when we support navigator.serviceWorker in dedicated workers.
162 int ServiceWorkerProviderContext::installing_handle_id() const {
163 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
164 return installing_
? installing_
->info().handle_id
165 : kInvalidServiceWorkerHandleId
;
168 int ServiceWorkerProviderContext::waiting_handle_id() const {
169 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
170 return waiting_
? waiting_
->info().handle_id
171 : kInvalidServiceWorkerHandleId
;
174 int ServiceWorkerProviderContext::active_handle_id() const {
175 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
176 return active_
? active_
->info().handle_id
177 : kInvalidServiceWorkerHandleId
;
180 int ServiceWorkerProviderContext::controller_handle_id() const {
181 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
182 return controller_
? controller_
->info().handle_id
183 : kInvalidServiceWorkerHandleId
;
186 int ServiceWorkerProviderContext::registration_handle_id() const {
187 DCHECK(main_thread_loop_proxy_
->RunsTasksOnCurrentThread());
188 return registration_
? registration_
->info().handle_id
189 : kInvalidServiceWorkerRegistrationHandleId
;
192 bool ServiceWorkerProviderContext::IsAssociatedWithRegistration(
193 int registration_handle_id
) const {
196 if (registration_handle_id
== kInvalidServiceWorkerRegistrationHandleId
)
198 return registration_
->info().handle_id
== registration_handle_id
;
201 } // namespace content