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/browser/navigator_connect/navigator_connect_context_impl.h" | 5 #include "content/browser/navigator_connect/navigator_connect_context_impl.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
| 9 #include "base/stl_util.h" |
9 #include "content/browser/message_port_service.h" | 10 #include "content/browser/message_port_service.h" |
10 #include "content/browser/navigator_connect/service_port_service_impl.h" | 11 #include "content/browser/navigator_connect/service_port_service_impl.h" |
11 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 12 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
12 #include "content/common/service_worker/service_worker_utils.h" | 13 #include "content/common/service_worker/service_worker_utils.h" |
13 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
14 #include "content/public/browser/navigator_connect_service_factory.h" | 15 #include "content/public/browser/navigator_connect_service_factory.h" |
15 #include "content/public/common/navigator_connect_client.h" | 16 #include "content/public/common/navigator_connect_client.h" |
| 17 #include "mojo/common/url_type_converters.h" |
16 | 18 |
17 namespace content { | 19 namespace content { |
18 | 20 |
19 struct NavigatorConnectContextImpl::Port { | 21 struct NavigatorConnectContextImpl::Port { |
20 // ID of this port. | 22 // ID of this port. |
21 int id; | 23 int id; |
22 // ID of the port this port is connected to. | 24 // ID of the port this port is connected to. |
23 int entangled_id; | 25 int entangled_id; |
24 | 26 |
25 // Service url and client origin describing this connection. These fields will | 27 // Service url and client origin describing this connection. These fields will |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 int client_port_id, | 134 int client_port_id, |
133 int service_port_id, | 135 int service_port_id, |
134 ServiceWorkerStatusCode status, | 136 ServiceWorkerStatusCode status, |
135 const scoped_refptr<ServiceWorkerRegistration>& registration) { | 137 const scoped_refptr<ServiceWorkerRegistration>& registration) { |
136 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 138 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
137 DCHECK(ports_.find(client_port_id) != ports_.end()); | 139 DCHECK(ports_.find(client_port_id) != ports_.end()); |
138 DCHECK(ports_.find(service_port_id) != ports_.end()); | 140 DCHECK(ports_.find(service_port_id) != ports_.end()); |
139 | 141 |
140 if (status != SERVICE_WORKER_OK) { | 142 if (status != SERVICE_WORKER_OK) { |
141 // No service worker found, reject connection attempt. | 143 // No service worker found, reject connection attempt. |
142 OnConnectResult(callback, client_port_id, service_port_id, registration, | 144 OnConnectError(callback, client_port_id, service_port_id, status); |
143 status, false, base::string16(), base::string16()); | |
144 return; | 145 return; |
145 } | 146 } |
146 | 147 |
147 ServiceWorkerVersion* active_version = registration->active_version(); | 148 ServiceWorkerVersion* active_version = registration->active_version(); |
148 DCHECK(active_version); | 149 DCHECK(active_version); |
149 | 150 |
150 Port& service_port = ports_[service_port_id]; | 151 Port& service_port = ports_[service_port_id]; |
151 service_port.service_worker_registration_id = registration->id(); | 152 service_port.service_worker_registration_id = registration->id(); |
152 service_port.service_worker_registration_origin = | 153 service_port.service_worker_registration_origin = |
153 registration->pattern().GetOrigin(); | 154 registration->pattern().GetOrigin(); |
154 | 155 |
155 active_version->DispatchServicePortConnectEvent( | 156 active_version->RunAfterStartWorker( |
| 157 base::Bind(&NavigatorConnectContextImpl::OnConnectError, this, callback, |
| 158 client_port_id, service_port_id), |
| 159 base::Bind(&NavigatorConnectContextImpl::DispatchConnectEvent, this, |
| 160 callback, client_port_id, service_port_id, registration, |
| 161 make_scoped_refptr(active_version))); |
| 162 } |
| 163 |
| 164 void NavigatorConnectContextImpl::DispatchConnectEvent( |
| 165 const ConnectCallback& callback, |
| 166 int client_port_id, |
| 167 int service_port_id, |
| 168 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, |
| 169 const scoped_refptr<ServiceWorkerVersion>& worker) { |
| 170 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 171 DCHECK(ContainsKey(ports_, client_port_id)); |
| 172 DCHECK(ContainsKey(ports_, service_port_id)); |
| 173 |
| 174 const Port& service_port = ports_[service_port_id]; |
| 175 int request_id = worker->StartRequest( |
| 176 ServiceWorkerMetrics::EventType::SERVICE_PORT_CONNECT, |
| 177 base::Bind(&NavigatorConnectContextImpl::OnConnectError, this, callback, |
| 178 client_port_id, service_port_id)); |
| 179 base::WeakPtr<ServicePortDispatcher> dispatcher = |
| 180 worker->GetMojoServiceForRequest<ServicePortDispatcher>(request_id); |
| 181 dispatcher->Connect( |
| 182 mojo::String::From(service_port.target_url), |
| 183 mojo::String::From(service_port.client_origin), service_port_id, |
156 base::Bind(&NavigatorConnectContextImpl::OnConnectResult, this, callback, | 184 base::Bind(&NavigatorConnectContextImpl::OnConnectResult, this, callback, |
157 client_port_id, service_port_id, registration), | 185 client_port_id, service_port_id, service_worker_registration, |
158 service_port.target_url, service_port.client_origin, service_port_id); | 186 worker, request_id)); |
159 } | 187 } |
160 | 188 |
161 void NavigatorConnectContextImpl::ServicePortServiceDestroyed( | 189 void NavigatorConnectContextImpl::ServicePortServiceDestroyed( |
162 ServicePortServiceImpl* service_port_service) { | 190 ServicePortServiceImpl* service_port_service) { |
163 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 191 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
164 for (auto& port : ports_) { | 192 for (auto& port : ports_) { |
165 if (port.second.service != service_port_service) | 193 if (port.second.service != service_port_service) |
166 continue; | 194 continue; |
167 port.second.service = nullptr; | 195 port.second.service = nullptr; |
168 // TODO(mek): Should actually inform other side of connections that the | 196 // TODO(mek): Should actually inform other side of connections that the |
169 // connection was closed, or in the case of service workers somehow keep | 197 // connection was closed, or in the case of service workers somehow keep |
170 // track of the connection. | 198 // track of the connection. |
171 } | 199 } |
172 } | 200 } |
173 | 201 |
| 202 void NavigatorConnectContextImpl::OnConnectError( |
| 203 const ConnectCallback& callback, |
| 204 int client_port_id, |
| 205 int service_port_id, |
| 206 ServiceWorkerStatusCode status) { |
| 207 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 208 // Destroy ports since connection failed. |
| 209 ports_.erase(service_port_id); |
| 210 ports_.erase(client_port_id); |
| 211 callback.Run(MSG_ROUTING_NONE, false); |
| 212 } |
| 213 |
174 void NavigatorConnectContextImpl::OnConnectResult( | 214 void NavigatorConnectContextImpl::OnConnectResult( |
175 const ConnectCallback& callback, | 215 const ConnectCallback& callback, |
176 int client_port_id, | 216 int client_port_id, |
177 int service_port_id, | 217 int service_port_id, |
178 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, | 218 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, |
179 ServiceWorkerStatusCode status, | 219 const scoped_refptr<ServiceWorkerVersion>& worker, |
180 bool accept_connection, | 220 int request_id, |
181 const base::string16& name, | 221 ServicePortConnectResult result, |
182 const base::string16& data) { | 222 const mojo::String& name, |
| 223 const mojo::String& data) { |
183 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 224 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
184 if (accept_connection) { | 225 |
185 // TODO(mek): Might have to do something else if the client connection got | 226 if (!worker->FinishRequest(request_id)) |
186 // severed while the service side connection was being set up. | 227 return; |
187 callback.Run(client_port_id, true); | 228 |
188 } else { | 229 if (result != SERVICE_PORT_CONNECT_RESULT_ACCEPT) { |
189 // Destroy ports since connection failed. | 230 OnConnectError(callback, client_port_id, service_port_id, |
190 ports_.erase(service_port_id); | 231 SERVICE_WORKER_ERROR_FAILED); |
191 ports_.erase(client_port_id); | 232 return; |
192 callback.Run(MSG_ROUTING_NONE, false); | |
193 } | 233 } |
| 234 |
| 235 // TODO(mek): Might have to do something else if the client connection got |
| 236 // severed while the service side connection was being set up. |
| 237 callback.Run(client_port_id, true); |
194 } | 238 } |
195 | 239 |
196 void NavigatorConnectContextImpl::DeliverMessage( | 240 void NavigatorConnectContextImpl::DeliverMessage( |
197 int port_id, | 241 int port_id, |
198 const base::string16& message, | 242 const base::string16& message, |
199 const std::vector<TransferredMessagePort>& sent_message_ports, | 243 const std::vector<TransferredMessagePort>& sent_message_ports, |
200 ServiceWorkerStatusCode service_worker_status, | 244 ServiceWorkerStatusCode service_worker_status, |
201 const scoped_refptr<ServiceWorkerRegistration>& | 245 const scoped_refptr<ServiceWorkerRegistration>& |
202 service_worker_registration) { | 246 service_worker_registration) { |
203 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 247 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
204 DCHECK(ports_.find(port_id) != ports_.end()); | 248 DCHECK(ports_.find(port_id) != ports_.end()); |
205 | 249 |
206 if (service_worker_status != SERVICE_WORKER_OK) { | 250 if (service_worker_status != SERVICE_WORKER_OK) { |
207 // TODO(mek): Do something when no service worker was found. | 251 // TODO(mek): Do something when no service worker was found. |
208 return; | 252 return; |
209 } | 253 } |
210 | 254 |
211 ServiceWorkerVersion* active_version = | 255 ServiceWorkerVersion* active_version = |
212 service_worker_registration->active_version(); | 256 service_worker_registration->active_version(); |
213 DCHECK(active_version); | 257 DCHECK(active_version); |
214 | 258 |
215 const Port& port = ports_[port_id]; | 259 const Port& port = ports_[port_id]; |
216 NavigatorConnectClient client(port.target_url, port.client_origin, port_id); | 260 NavigatorConnectClient client(port.target_url, port.client_origin, port_id); |
217 active_version->DispatchCrossOriginMessageEvent( | 261 active_version->DispatchCrossOriginMessageEvent( |
218 client, message, sent_message_ports, | 262 client, message, sent_message_ports, |
219 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 263 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
220 } | 264 } |
221 | 265 |
222 } // namespace content | 266 } // namespace content |
OLD | NEW |