| 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 |