• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/child/service_worker/service_worker_provider_context.h"
6 
7 #include "base/bind.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"
17 
18 namespace content {
19 
ServiceWorkerProviderContext(int provider_id)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());
29   DCHECK(dispatcher);
30   dispatcher->AddProviderContext(this);
31 }
32 
~ServiceWorkerProviderContext()33 ServiceWorkerProviderContext::~ServiceWorkerProviderContext() {
34   if (ServiceWorkerDispatcher* dispatcher =
35           ServiceWorkerDispatcher::GetThreadSpecificInstance()) {
36     dispatcher->RemoveProviderContext(this);
37   }
38 }
39 
installing()40 ServiceWorkerHandleReference* ServiceWorkerProviderContext::installing() {
41   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
42   return installing_.get();
43 }
44 
waiting()45 ServiceWorkerHandleReference* ServiceWorkerProviderContext::waiting() {
46   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
47   return waiting_.get();
48 }
49 
active()50 ServiceWorkerHandleReference* ServiceWorkerProviderContext::active() {
51   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
52   return active_.get();
53 }
54 
controller()55 ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() {
56   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
57   return controller_.get();
58 }
59 
60 ServiceWorkerRegistrationHandleReference*
registration()61 ServiceWorkerProviderContext::registration() {
62   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
63   return registration_.get();
64 }
65 
66 ServiceWorkerVersionAttributes
GetVersionAttributes()67 ServiceWorkerProviderContext::GetVersionAttributes() {
68   ServiceWorkerVersionAttributes attrs;
69   if (installing())
70     attrs.installing = installing()->info();
71   if (waiting())
72     attrs.waiting = waiting()->info();
73   if (active())
74     attrs.active = active()->info();
75   return attrs;
76 }
77 
OnAssociateRegistration(const ServiceWorkerRegistrationObjectInfo & info,const ServiceWorkerVersionAttributes & attrs)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());
91 }
92 
OnDisassociateRegistration()93 void ServiceWorkerProviderContext::OnDisassociateRegistration() {
94   controller_.reset();
95   active_.reset();
96   waiting_.reset();
97   installing_.reset();
98   registration_.reset();
99 }
100 
OnServiceWorkerStateChanged(int handle_id,blink::WebServiceWorkerState state)101 void ServiceWorkerProviderContext::OnServiceWorkerStateChanged(
102     int handle_id,
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();
113 
114   // We should only get messages for ServiceWorkers associated with
115   // this provider.
116   DCHECK(which);
117 
118   which->set_state(state);
119 
120   // TODO(kinuko): We can forward the message to other threads here
121   // when we support navigator.serviceWorker in dedicated workers.
122 }
123 
OnSetInstallingServiceWorker(int registration_handle_id,const ServiceWorkerObjectInfo & info)124 void ServiceWorkerProviderContext::OnSetInstallingServiceWorker(
125     int registration_handle_id,
126     const ServiceWorkerObjectInfo& info) {
127   DCHECK(IsAssociatedWithRegistration(registration_handle_id));
128   installing_ =
129       ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
130 }
131 
OnSetWaitingServiceWorker(int registration_handle_id,const ServiceWorkerObjectInfo & info)132 void ServiceWorkerProviderContext::OnSetWaitingServiceWorker(
133     int registration_handle_id,
134     const ServiceWorkerObjectInfo& info) {
135   DCHECK(IsAssociatedWithRegistration(registration_handle_id));
136   waiting_ =
137       ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
138 }
139 
OnSetActiveServiceWorker(int registration_handle_id,const ServiceWorkerObjectInfo & info)140 void ServiceWorkerProviderContext::OnSetActiveServiceWorker(
141     int registration_handle_id,
142     const ServiceWorkerObjectInfo& info) {
143   DCHECK(IsAssociatedWithRegistration(registration_handle_id));
144   active_ =
145       ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
146 }
147 
OnSetControllerServiceWorker(int registration_handle_id,const ServiceWorkerObjectInfo & info)148 void ServiceWorkerProviderContext::OnSetControllerServiceWorker(
149     int registration_handle_id,
150     const ServiceWorkerObjectInfo& info) {
151   DCHECK(IsAssociatedWithRegistration(registration_handle_id));
152 
153   // This context is is the primary owner of this handle, keeps the
154   // initial reference until it goes away.
155   controller_ =
156       ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
157 
158   // TODO(kinuko): We can forward the message to other threads here
159   // when we support navigator.serviceWorker in dedicated workers.
160 }
161 
installing_handle_id() const162 int ServiceWorkerProviderContext::installing_handle_id() const {
163   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
164   return installing_ ? installing_->info().handle_id
165                      : kInvalidServiceWorkerHandleId;
166 }
167 
waiting_handle_id() const168 int ServiceWorkerProviderContext::waiting_handle_id() const {
169   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
170   return waiting_ ? waiting_->info().handle_id
171                   : kInvalidServiceWorkerHandleId;
172 }
173 
active_handle_id() const174 int ServiceWorkerProviderContext::active_handle_id() const {
175   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
176   return active_ ? active_->info().handle_id
177                  : kInvalidServiceWorkerHandleId;
178 }
179 
controller_handle_id() const180 int ServiceWorkerProviderContext::controller_handle_id() const {
181   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
182   return controller_ ? controller_->info().handle_id
183                      : kInvalidServiceWorkerHandleId;
184 }
185 
registration_handle_id() const186 int ServiceWorkerProviderContext::registration_handle_id() const {
187   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
188   return registration_ ? registration_->info().handle_id
189                        : kInvalidServiceWorkerRegistrationHandleId;
190 }
191 
IsAssociatedWithRegistration(int registration_handle_id) const192 bool ServiceWorkerProviderContext::IsAssociatedWithRegistration(
193     int registration_handle_id) const {
194   if (!registration_)
195     return false;
196   if (registration_handle_id == kInvalidServiceWorkerRegistrationHandleId)
197     return false;
198   return registration_->info().handle_id == registration_handle_id;
199 }
200 
201 }  // namespace content
202