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