Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / content / child / service_worker / service_worker_provider_context.cc
blob56e543311a17eaeaa470067cc4b686775f786464
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/bind.h"
8 #include "base/location.h"
9 #include "base/stl_util.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/child/child_thread_impl.h"
12 #include "content/child/service_worker/service_worker_dispatcher.h"
13 #include "content/child/service_worker/service_worker_handle_reference.h"
14 #include "content/child/service_worker/service_worker_registration_handle_reference.h"
15 #include "content/child/thread_safe_sender.h"
16 #include "content/child/worker_task_runner.h"
17 #include "content/common/service_worker/service_worker_messages.h"
19 namespace content {
21 ServiceWorkerProviderContext::ServiceWorkerProviderContext(int provider_id)
22 : provider_id_(provider_id),
23 main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
24 if (!ChildThreadImpl::current())
25 return; // May be null in some tests.
26 thread_safe_sender_ = ChildThreadImpl::current()->thread_safe_sender();
27 ServiceWorkerDispatcher* dispatcher =
28 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
29 thread_safe_sender_.get(), main_thread_task_runner_.get());
30 DCHECK(dispatcher);
31 dispatcher->AddProviderContext(this);
34 ServiceWorkerProviderContext::~ServiceWorkerProviderContext() {
35 if (ServiceWorkerDispatcher* dispatcher =
36 ServiceWorkerDispatcher::GetThreadSpecificInstance()) {
37 // Remove this context from the dispatcher living on the main thread.
38 dispatcher->RemoveProviderContext(this);
42 ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() {
43 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
44 return controller_.get();
47 bool ServiceWorkerProviderContext::GetRegistrationInfoAndVersionAttributes(
48 ServiceWorkerRegistrationObjectInfo* info,
49 ServiceWorkerVersionAttributes* attrs) {
50 base::AutoLock lock(lock_);
51 if (!registration_)
52 return false;
54 *info = registration_->info();
55 if (installing_)
56 attrs->installing = installing_->info();
57 if (waiting_)
58 attrs->waiting = waiting_->info();
59 if (active_)
60 attrs->active = active_->info();
61 return true;
64 void ServiceWorkerProviderContext::SetVersionAttributes(
65 ChangedVersionAttributesMask mask,
66 const ServiceWorkerVersionAttributes& attrs) {
67 base::AutoLock lock(lock_);
68 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
69 DCHECK(registration_);
71 if (mask.installing_changed()) {
72 installing_ = ServiceWorkerHandleReference::Adopt(
73 attrs.installing, thread_safe_sender_.get());
75 if (mask.waiting_changed()) {
76 waiting_ = ServiceWorkerHandleReference::Adopt(
77 attrs.waiting, thread_safe_sender_.get());
79 if (mask.active_changed()) {
80 active_ = ServiceWorkerHandleReference::Adopt(
81 attrs.active, thread_safe_sender_.get());
85 void ServiceWorkerProviderContext::OnAssociateRegistration(
86 const ServiceWorkerRegistrationObjectInfo& info,
87 const ServiceWorkerVersionAttributes& attrs) {
88 base::AutoLock lock(lock_);
89 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
90 DCHECK(!registration_);
91 DCHECK_NE(kInvalidServiceWorkerRegistrationId, info.registration_id);
92 DCHECK_NE(kInvalidServiceWorkerRegistrationHandleId, info.handle_id);
94 registration_ = ServiceWorkerRegistrationHandleReference::Adopt(
95 info, thread_safe_sender_.get());
96 installing_ = ServiceWorkerHandleReference::Adopt(
97 attrs.installing, thread_safe_sender_.get());
98 waiting_ = ServiceWorkerHandleReference::Adopt(
99 attrs.waiting, thread_safe_sender_.get());
100 active_ = ServiceWorkerHandleReference::Adopt(
101 attrs.active, thread_safe_sender_.get());
104 void ServiceWorkerProviderContext::OnDisassociateRegistration() {
105 base::AutoLock lock(lock_);
106 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
108 controller_.reset();
109 active_.reset();
110 waiting_.reset();
111 installing_.reset();
112 registration_.reset();
115 void ServiceWorkerProviderContext::OnServiceWorkerStateChanged(
116 int handle_id,
117 blink::WebServiceWorkerState state) {
118 base::AutoLock lock(lock_);
119 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
121 ServiceWorkerHandleReference* which = NULL;
122 if (handle_id == controller_handle_id())
123 which = controller_.get();
124 else if (handle_id == active_handle_id())
125 which = active_.get();
126 else if (handle_id == waiting_handle_id())
127 which = waiting_.get();
128 else if (handle_id == installing_handle_id())
129 which = installing_.get();
131 // We should only get messages for ServiceWorkers associated with
132 // this provider.
133 DCHECK(which);
135 which->set_state(state);
137 // TODO(kinuko): We can forward the message to other threads here
138 // when we support navigator.serviceWorker in dedicated workers.
141 void ServiceWorkerProviderContext::OnSetControllerServiceWorker(
142 const ServiceWorkerObjectInfo& info) {
143 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
144 DCHECK(registration_);
146 // This context is is the primary owner of this handle, keeps the
147 // initial reference until it goes away.
148 controller_ =
149 ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
151 // TODO(kinuko): We can forward the message to other threads here
152 // when we support navigator.serviceWorker in dedicated workers.
155 int ServiceWorkerProviderContext::installing_handle_id() const {
156 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
157 return installing_ ? installing_->info().handle_id
158 : kInvalidServiceWorkerHandleId;
161 int ServiceWorkerProviderContext::waiting_handle_id() const {
162 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
163 return waiting_ ? waiting_->info().handle_id
164 : kInvalidServiceWorkerHandleId;
167 int ServiceWorkerProviderContext::active_handle_id() const {
168 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
169 return active_ ? active_->info().handle_id
170 : kInvalidServiceWorkerHandleId;
173 int ServiceWorkerProviderContext::controller_handle_id() const {
174 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
175 return controller_ ? controller_->info().handle_id
176 : kInvalidServiceWorkerHandleId;
179 int ServiceWorkerProviderContext::registration_handle_id() const {
180 DCHECK(main_thread_task_runner_->RunsTasksOnCurrentThread());
181 return registration_ ? registration_->info().handle_id
182 : kInvalidServiceWorkerRegistrationHandleId;
185 void ServiceWorkerProviderContext::DestructOnMainThread() const {
186 if (!main_thread_task_runner_->RunsTasksOnCurrentThread() &&
187 main_thread_task_runner_->DeleteSoon(FROM_HERE, this)) {
188 return;
190 delete this;
193 } // namespace content