OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/service_worker/service_worker_provider_context.h" | 5 #include "content/child/service_worker/service_worker_provider_context.h" |
6 | 6 |
7 #include "base/thread_task_runner_handle.h" | 7 #include "base/thread_task_runner_handle.h" |
8 #include "content/child/child_thread_impl.h" | 8 #include "content/child/child_thread_impl.h" |
9 #include "content/child/service_worker/service_worker_dispatcher.h" | 9 #include "content/child/service_worker/service_worker_dispatcher.h" |
10 #include "content/child/service_worker/service_worker_handle_reference.h" | 10 #include "content/child/service_worker/service_worker_handle_reference.h" |
11 #include "content/child/service_worker/service_worker_registration_handle_refere
nce.h" | 11 #include "content/child/service_worker/service_worker_registration_handle_refere
nce.h" |
12 #include "content/child/thread_safe_sender.h" | 12 #include "content/child/thread_safe_sender.h" |
13 #include "content/child/worker_task_runner.h" | 13 #include "content/child/worker_task_runner.h" |
14 | 14 |
15 namespace content { | 15 namespace content { |
16 | 16 |
17 ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id) | 17 class ServiceWorkerProviderContext::Delegate { |
| 18 public: |
| 19 virtual ~Delegate(){}; |
| 20 virtual void AssociateRegistration( |
| 21 scoped_ptr<ServiceWorkerRegistrationHandleReference> registration, |
| 22 scoped_ptr<ServiceWorkerHandleReference> installing, |
| 23 scoped_ptr<ServiceWorkerHandleReference> waiting, |
| 24 scoped_ptr<ServiceWorkerHandleReference> active) = 0; |
| 25 virtual void DisassociateRegistration() = 0; |
| 26 virtual void GetAssociatedRegistration( |
| 27 ServiceWorkerRegistrationObjectInfo* info, |
| 28 ServiceWorkerVersionAttributes* attrs) = 0; |
| 29 virtual void SetController( |
| 30 scoped_ptr<ServiceWorkerHandleReference> controller) = 0; |
| 31 virtual ServiceWorkerHandleReference* controller() = 0; |
| 32 }; |
| 33 |
| 34 // Delegate class for ServiceWorker client (Document, SharedWorker, etc) to |
| 35 // keep the associated registration and the controller until |
| 36 // ServiceWorkerContainer is initialized. |
| 37 class ServiceWorkerProviderContext::ControlleeDelegate |
| 38 : public ServiceWorkerProviderContext::Delegate { |
| 39 public: |
| 40 ControlleeDelegate() {} |
| 41 ~ControlleeDelegate() override {} |
| 42 |
| 43 void AssociateRegistration( |
| 44 scoped_ptr<ServiceWorkerRegistrationHandleReference> registration, |
| 45 scoped_ptr<ServiceWorkerHandleReference> installing, |
| 46 scoped_ptr<ServiceWorkerHandleReference> waiting, |
| 47 scoped_ptr<ServiceWorkerHandleReference> active) override { |
| 48 DCHECK(!registration_); |
| 49 registration_ = registration.Pass(); |
| 50 } |
| 51 |
| 52 void DisassociateRegistration() override { |
| 53 controller_.reset(); |
| 54 registration_.reset(); |
| 55 } |
| 56 |
| 57 void SetController( |
| 58 scoped_ptr<ServiceWorkerHandleReference> controller) override { |
| 59 DCHECK(registration_); |
| 60 controller_ = controller.Pass(); |
| 61 } |
| 62 |
| 63 void GetAssociatedRegistration( |
| 64 ServiceWorkerRegistrationObjectInfo* info, |
| 65 ServiceWorkerVersionAttributes* attrs) override { |
| 66 NOTREACHED(); |
| 67 } |
| 68 |
| 69 ServiceWorkerHandleReference* controller() override { |
| 70 return controller_.get(); |
| 71 } |
| 72 |
| 73 private: |
| 74 scoped_ptr<ServiceWorkerRegistrationHandleReference> registration_; |
| 75 scoped_ptr<ServiceWorkerHandleReference> controller_; |
| 76 |
| 77 DISALLOW_COPY_AND_ASSIGN(ControlleeDelegate); |
| 78 }; |
| 79 |
| 80 // Delegate class for ServiceWorkerGlobalScope to keep the associated |
| 81 // registration and its versions until the execution context is initialized. |
| 82 class ServiceWorkerProviderContext::ControllerDelegate |
| 83 : public ServiceWorkerProviderContext::Delegate { |
| 84 public: |
| 85 ControllerDelegate() {} |
| 86 ~ControllerDelegate() override {} |
| 87 |
| 88 void AssociateRegistration( |
| 89 scoped_ptr<ServiceWorkerRegistrationHandleReference> registration, |
| 90 scoped_ptr<ServiceWorkerHandleReference> installing, |
| 91 scoped_ptr<ServiceWorkerHandleReference> waiting, |
| 92 scoped_ptr<ServiceWorkerHandleReference> active) override { |
| 93 DCHECK(!registration_); |
| 94 registration_ = registration.Pass(); |
| 95 installing_ = active.Pass(); |
| 96 waiting_ = waiting.Pass(); |
| 97 active_ = active.Pass(); |
| 98 } |
| 99 |
| 100 void DisassociateRegistration() override { |
| 101 // ServiceWorkerGlobalScope is never disassociated. |
| 102 NOTREACHED(); |
| 103 } |
| 104 |
| 105 void SetController( |
| 106 scoped_ptr<ServiceWorkerHandleReference> controller) override { |
| 107 NOTREACHED(); |
| 108 } |
| 109 |
| 110 void GetAssociatedRegistration( |
| 111 ServiceWorkerRegistrationObjectInfo* info, |
| 112 ServiceWorkerVersionAttributes* attrs) override { |
| 113 DCHECK(registration_); |
| 114 *info = registration_->info(); |
| 115 if (installing_) |
| 116 attrs->installing = installing_->info(); |
| 117 if (waiting_) |
| 118 attrs->waiting = waiting_->info(); |
| 119 if (active_) |
| 120 attrs->active = active_->info(); |
| 121 } |
| 122 |
| 123 ServiceWorkerHandleReference* controller() override { |
| 124 NOTREACHED(); |
| 125 return nullptr; |
| 126 } |
| 127 |
| 128 private: |
| 129 scoped_ptr<ServiceWorkerRegistrationHandleReference> registration_; |
| 130 scoped_ptr<ServiceWorkerHandleReference> installing_; |
| 131 scoped_ptr<ServiceWorkerHandleReference> waiting_; |
| 132 scoped_ptr<ServiceWorkerHandleReference> active_; |
| 133 |
| 134 ServiceWorkerProviderContext* context_; |
| 135 |
| 136 DISALLOW_COPY_AND_ASSIGN(ControllerDelegate); |
| 137 }; |
| 138 |
| 139 ServiceWorkerProviderContext::ServiceWorkerProviderContext( |
| 140 int provider_id, |
| 141 ServiceWorkerProviderType provider_type) |
18 : provider_id_(provider_id), | 142 : provider_id_(provider_id), |
19 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) { | 143 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) { |
| 144 if (provider_type == SERVICE_WORKER_PROVIDER_FOR_CONTROLLER) |
| 145 delegate_.reset(new ControllerDelegate); |
| 146 else |
| 147 delegate_.reset(new ControlleeDelegate); |
| 148 |
20 if (!ChildThreadImpl::current()) | 149 if (!ChildThreadImpl::current()) |
21 return; // May be null in some tests. | 150 return; // May be null in some tests. |
22 thread_safe_sender_ = ChildThreadImpl::current()->thread_safe_sender(); | 151 thread_safe_sender_ = ChildThreadImpl::current()->thread_safe_sender(); |
| 152 |
23 ServiceWorkerDispatcher* dispatcher = | 153 ServiceWorkerDispatcher* dispatcher = |
24 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( | 154 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( |
25 thread_safe_sender_.get(), main_thread_task_runner_.get()); | 155 thread_safe_sender_.get(), main_thread_task_runner_.get()); |
26 DCHECK(dispatcher); | |
27 dispatcher->AddProviderContext(this); | 156 dispatcher->AddProviderContext(this); |
28 } | 157 } |
29 | 158 |
30 ServiceWorkerProviderContext::~ServiceWorkerProviderContext() { | 159 ServiceWorkerProviderContext::~ServiceWorkerProviderContext() { |
31 if (ServiceWorkerDispatcher* dispatcher = | 160 if (ServiceWorkerDispatcher* dispatcher = |
32 ServiceWorkerDispatcher::GetThreadSpecificInstance()) { | 161 ServiceWorkerDispatcher::GetThreadSpecificInstance()) { |
33 // Remove this context from the dispatcher living on the main thread. | 162 // Remove this context from the dispatcher living on the main thread. |
34 dispatcher->RemoveProviderContext(this); | 163 dispatcher->RemoveProviderContext(this); |
35 } | 164 } |
36 } | 165 } |
37 | 166 |
38 ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() { | |
39 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); | |
40 return controller_.get(); | |
41 } | |
42 | |
43 bool ServiceWorkerProviderContext::GetRegistrationInfoAndVersionAttributes( | |
44 ServiceWorkerRegistrationObjectInfo* info, | |
45 ServiceWorkerVersionAttributes* attrs) { | |
46 DCHECK(!main_thread_task_runner_->RunsTasksOnCurrentThread()); | |
47 base::AutoLock lock(lock_); | |
48 if (!registration_) | |
49 return false; | |
50 | |
51 *info = registration_->info(); | |
52 if (installing_) | |
53 attrs->installing = installing_->info(); | |
54 if (waiting_) | |
55 attrs->waiting = waiting_->info(); | |
56 if (active_) | |
57 attrs->active = active_->info(); | |
58 return true; | |
59 } | |
60 | |
61 void ServiceWorkerProviderContext::OnAssociateRegistration( | 167 void ServiceWorkerProviderContext::OnAssociateRegistration( |
62 const ServiceWorkerRegistrationObjectInfo& info, | 168 const ServiceWorkerRegistrationObjectInfo& info, |
63 const ServiceWorkerVersionAttributes& attrs) { | 169 const ServiceWorkerVersionAttributes& attrs) { |
64 base::AutoLock lock(lock_); | |
65 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); | 170 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); |
66 DCHECK(!registration_); | 171 delegate_->AssociateRegistration( |
67 DCHECK_NE(kInvalidServiceWorkerRegistrationId, info.registration_id); | 172 ServiceWorkerRegistrationHandleReference::Adopt( |
68 DCHECK_NE(kInvalidServiceWorkerRegistrationHandleId, info.handle_id); | 173 info, thread_safe_sender_.get()), |
69 | 174 ServiceWorkerHandleReference::Adopt(attrs.installing, |
70 registration_ = ServiceWorkerRegistrationHandleReference::Adopt( | 175 thread_safe_sender_.get()), |
71 info, thread_safe_sender_.get()); | 176 ServiceWorkerHandleReference::Adopt(attrs.waiting, |
72 installing_ = ServiceWorkerHandleReference::Adopt( | 177 thread_safe_sender_.get()), |
73 attrs.installing, thread_safe_sender_.get()); | 178 ServiceWorkerHandleReference::Adopt(attrs.active, |
74 waiting_ = ServiceWorkerHandleReference::Adopt( | 179 thread_safe_sender_.get())); |
75 attrs.waiting, thread_safe_sender_.get()); | |
76 active_ = ServiceWorkerHandleReference::Adopt( | |
77 attrs.active, thread_safe_sender_.get()); | |
78 } | 180 } |
79 | 181 |
80 void ServiceWorkerProviderContext::OnDisassociateRegistration() { | 182 void ServiceWorkerProviderContext::OnDisassociateRegistration() { |
81 base::AutoLock lock(lock_); | |
82 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); | 183 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); |
83 | 184 delegate_->DisassociateRegistration(); |
84 controller_.reset(); | |
85 active_.reset(); | |
86 waiting_.reset(); | |
87 installing_.reset(); | |
88 registration_.reset(); | |
89 } | 185 } |
90 | 186 |
91 void ServiceWorkerProviderContext::OnSetControllerServiceWorker( | 187 void ServiceWorkerProviderContext::OnSetControllerServiceWorker( |
92 const ServiceWorkerObjectInfo& info) { | 188 const ServiceWorkerObjectInfo& info) { |
93 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); | 189 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); |
94 DCHECK(registration_); | 190 if (info.version_id == kInvalidServiceWorkerVersionId) { |
| 191 delegate_->SetController(scoped_ptr<ServiceWorkerHandleReference>()); |
| 192 return; |
| 193 } |
| 194 delegate_->SetController( |
| 195 ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get())); |
| 196 } |
95 | 197 |
96 if (info.version_id == kInvalidServiceWorkerVersionId) { | 198 void ServiceWorkerProviderContext::GetAssociatedRegistration( |
97 controller_.reset(); | 199 ServiceWorkerRegistrationObjectInfo* info, |
98 } else { | 200 ServiceWorkerVersionAttributes* attrs) { |
99 // This context is is the primary owner of this handle, keeps the | 201 DCHECK(!main_thread_task_runner_->RunsTasksOnCurrentThread()); |
100 // initial reference until it goes away. | 202 delegate_->GetAssociatedRegistration(info, attrs); |
101 controller_ = | 203 } |
102 ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get()); | 204 |
103 } | 205 ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() { |
104 // TODO(kinuko): We can forward the message to other threads here | 206 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread()); |
105 // when we support navigator.serviceWorker in dedicated workers. | 207 return delegate_->controller(); |
106 } | 208 } |
107 | 209 |
108 void ServiceWorkerProviderContext::DestructOnMainThread() const { | 210 void ServiceWorkerProviderContext::DestructOnMainThread() const { |
109 if (!main_thread_task_runner_->RunsTasksOnCurrentThread() && | 211 if (!main_thread_task_runner_->RunsTasksOnCurrentThread() && |
110 main_thread_task_runner_->DeleteSoon(FROM_HERE, this)) { | 212 main_thread_task_runner_->DeleteSoon(FROM_HERE, this)) { |
111 return; | 213 return; |
112 } | 214 } |
113 delete this; | 215 delete this; |
114 } | 216 } |
115 | 217 |
116 } // namespace content | 218 } // namespace content |
OLD | NEW |