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