OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/service_worker/service_worker_client_utils.h" | 5 #include "content/browser/service_worker/service_worker_client_utils.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "content/browser/frame_host/frame_tree_node.h" | 10 #include "content/browser/frame_host/frame_tree_node.h" |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 169 } |
170 | 170 |
171 void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context, | 171 void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context, |
172 const GURL& origin, | 172 const GURL& origin, |
173 const NavigationCallback& callback, | 173 const NavigationCallback& callback, |
174 int render_process_id, | 174 int render_process_id, |
175 int render_frame_id) { | 175 int render_frame_id) { |
176 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 176 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
177 | 177 |
178 if (!context) { | 178 if (!context) { |
179 callback.Run(SERVICE_WORKER_ERROR_ABORT, std::string(), | 179 callback.Run(SERVICE_WORKER_ERROR_ABORT, ServiceWorkerClientInfo()); |
180 ServiceWorkerClientInfo()); | |
181 return; | 180 return; |
182 } | 181 } |
183 | 182 |
184 if (render_process_id == ChildProcessHost::kInvalidUniqueID && | 183 if (render_process_id == ChildProcessHost::kInvalidUniqueID && |
185 render_frame_id == MSG_ROUTING_NONE) { | 184 render_frame_id == MSG_ROUTING_NONE) { |
186 callback.Run(SERVICE_WORKER_ERROR_FAILED, std::string(), | 185 callback.Run(SERVICE_WORKER_ERROR_FAILED, ServiceWorkerClientInfo()); |
187 ServiceWorkerClientInfo()); | |
188 return; | 186 return; |
189 } | 187 } |
190 | 188 |
191 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 189 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
192 context->GetClientProviderHostIterator(origin); | 190 context->GetClientProviderHostIterator(origin); |
193 !it->IsAtEnd(); it->Advance()) { | 191 !it->IsAtEnd(); it->Advance()) { |
194 ServiceWorkerProviderHost* provider_host = it->GetProviderHost(); | 192 ServiceWorkerProviderHost* provider_host = it->GetProviderHost(); |
195 if (provider_host->process_id() != render_process_id || | 193 if (provider_host->process_id() != render_process_id || |
196 provider_host->frame_id() != render_frame_id) { | 194 provider_host->frame_id() != render_frame_id) { |
197 continue; | 195 continue; |
198 } | 196 } |
199 provider_host->GetWindowClientInfo( | 197 provider_host->GetWindowClientInfo(base::Bind(callback, SERVICE_WORKER_OK)); |
200 base::Bind(callback, SERVICE_WORKER_OK, provider_host->client_uuid())); | |
201 return; | 198 return; |
202 } | 199 } |
203 | 200 |
204 // If here, it means that no provider_host was found, in which case, the | 201 // If here, it means that no provider_host was found, in which case, the |
205 // renderer should still be informed that the window was opened. | 202 // renderer should still be informed that the window was opened. |
206 callback.Run(SERVICE_WORKER_OK, std::string(), ServiceWorkerClientInfo()); | 203 callback.Run(SERVICE_WORKER_OK, ServiceWorkerClientInfo()); |
207 } | 204 } |
208 | 205 |
209 void AddWindowClient( | 206 void AddWindowClient( |
210 ServiceWorkerProviderHost* host, | 207 ServiceWorkerProviderHost* host, |
211 std::vector<base::Tuple<int, int, std::string>>* client_info) { | 208 std::vector<base::Tuple<int, int, std::string>>* client_info) { |
212 if (host->client_type() != blink::WebServiceWorkerClientTypeWindow) | 209 if (host->client_type() != blink::WebServiceWorkerClientTypeWindow) |
213 return; | 210 return; |
214 client_info->push_back(base::MakeTuple(host->process_id(), host->frame_id(), | 211 client_info->push_back(base::MakeTuple(host->process_id(), host->frame_id(), |
215 host->client_uuid())); | 212 host->client_uuid())); |
216 } | 213 } |
217 | 214 |
218 void AddNonWindowClient(ServiceWorkerProviderHost* host, | 215 void AddNonWindowClient(ServiceWorkerProviderHost* host, |
219 const ServiceWorkerClientQueryOptions& options, | 216 const ServiceWorkerClientQueryOptions& options, |
220 ServiceWorkerClients* clients) { | 217 ServiceWorkerClients* clients) { |
221 blink::WebServiceWorkerClientType host_client_type = host->client_type(); | 218 blink::WebServiceWorkerClientType host_client_type = host->client_type(); |
222 if (host_client_type == blink::WebServiceWorkerClientTypeWindow) | 219 if (host_client_type == blink::WebServiceWorkerClientTypeWindow) |
223 return; | 220 return; |
224 if (options.client_type != blink::WebServiceWorkerClientTypeAll && | 221 if (options.client_type != blink::WebServiceWorkerClientTypeAll && |
225 options.client_type != host_client_type) | 222 options.client_type != host_client_type) |
226 return; | 223 return; |
227 | 224 |
228 ServiceWorkerClientInfo client_info(blink::WebPageVisibilityStateHidden, | 225 ServiceWorkerClientInfo client_info( |
229 false, // is_focused | 226 host->client_uuid(), blink::WebPageVisibilityStateHidden, |
230 host->document_url(), | 227 false, // is_focused |
231 REQUEST_CONTEXT_FRAME_TYPE_NONE, | 228 host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, base::TimeTicks(), |
232 base::TimeTicks(), host_client_type); | 229 host_client_type); |
233 client_info.client_uuid = host->client_uuid(); | |
234 clients->push_back(client_info); | 230 clients->push_back(client_info); |
235 } | 231 } |
236 | 232 |
237 void OnGetWindowClientsOnUI( | 233 void OnGetWindowClientsOnUI( |
238 // The tuple contains process_id, frame_id, client_uuid. | 234 // The tuple contains process_id, frame_id, client_uuid. |
239 const std::vector<base::Tuple<int, int, std::string>>& clients_info, | 235 const std::vector<base::Tuple<int, int, std::string>>& clients_info, |
240 const GURL& script_url, | 236 const GURL& script_url, |
241 const GetWindowClientsCallback& callback) { | 237 const GetWindowClientsCallback& callback) { |
242 scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients); | 238 scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients); |
243 | 239 |
244 for (const auto& it : clients_info) { | 240 for (const auto& it : clients_info) { |
245 ServiceWorkerClientInfo info = | 241 ServiceWorkerClientInfo info = |
246 ServiceWorkerProviderHost::GetWindowClientInfoOnUI(base::get<0>(it), | 242 ServiceWorkerProviderHost::GetWindowClientInfoOnUI( |
247 base::get<1>(it)); | 243 base::get<0>(it), base::get<1>(it), base::get<2>(it)); |
248 | 244 |
249 // If the request to the provider_host returned an empty | 245 // If the request to the provider_host returned an empty |
250 // ServiceWorkerClientInfo, that means that it wasn't possible to associate | 246 // ServiceWorkerClientInfo, that means that it wasn't possible to associate |
251 // it with a valid RenderFrameHost. It might be because the frame was killed | 247 // it with a valid RenderFrameHost. It might be because the frame was killed |
252 // or navigated in between. | 248 // or navigated in between. |
253 if (info.IsEmpty()) | 249 if (info.IsEmpty()) |
254 continue; | 250 continue; |
255 | 251 |
256 // We can get info for a frame that was navigating end ended up with a | 252 // We can get info for a frame that was navigating end ended up with a |
257 // different URL than expected. In such case, we should make sure to not | 253 // different URL than expected. In such case, we should make sure to not |
258 // expose cross-origin WindowClient. | 254 // expose cross-origin WindowClient. |
259 if (info.url.GetOrigin() != script_url.GetOrigin()) | 255 if (info.url.GetOrigin() != script_url.GetOrigin()) |
260 continue; | 256 continue; |
261 | 257 |
262 info.client_uuid = base::get<2>(it); | |
263 clients->push_back(info); | 258 clients->push_back(info); |
264 } | 259 } |
265 | 260 |
266 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 261 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
267 base::Bind(callback, base::Passed(&clients))); | 262 base::Bind(callback, base::Passed(&clients))); |
268 } | 263 } |
269 | 264 |
270 struct ServiceWorkerClientInfoSortMRU { | 265 struct ServiceWorkerClientInfoSortMRU { |
271 bool operator()(const ServiceWorkerClientInfo& a, | 266 bool operator()(const ServiceWorkerClientInfo& a, |
272 const ServiceWorkerClientInfo& b) const { | 267 const ServiceWorkerClientInfo& b) const { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 const base::WeakPtr<ServiceWorkerContextCore>& context, | 359 const base::WeakPtr<ServiceWorkerContextCore>& context, |
365 const NavigationCallback& callback) { | 360 const NavigationCallback& callback) { |
366 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 361 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
367 BrowserThread::PostTask( | 362 BrowserThread::PostTask( |
368 BrowserThread::UI, FROM_HERE, | 363 BrowserThread::UI, FROM_HERE, |
369 base::Bind( | 364 base::Bind( |
370 &NavigateClientOnUI, url, script_url, process_id, frame_id, | 365 &NavigateClientOnUI, url, script_url, process_id, frame_id, |
371 base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback))); | 366 base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback))); |
372 } | 367 } |
373 | 368 |
| 369 void GetClient( |
| 370 const base::WeakPtr<ServiceWorkerVersion>& controller, |
| 371 const std::string& client_uuid, |
| 372 const base::WeakPtr<ServiceWorkerContextCore>& context, |
| 373 const ServiceWorkerProviderHost::GetClientInfoCallback& callback) { |
| 374 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 375 |
| 376 ServiceWorkerProviderHost* provider_host = |
| 377 context->GetProviderHostByClientID(client_uuid); |
| 378 |
| 379 if (!provider_host) { |
| 380 // The client may already have been closed, just ignore. |
| 381 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 382 base::Bind(callback, ServiceWorkerClientInfo())); |
| 383 return; |
| 384 } |
| 385 |
| 386 if (provider_host->document_url().GetOrigin() != |
| 387 controller->script_url().GetOrigin()) { |
| 388 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 389 base::Bind(callback, ServiceWorkerClientInfo())); |
| 390 return; |
| 391 } |
| 392 |
| 393 if (provider_host->client_type() == blink::WebServiceWorkerClientTypeWindow) { |
| 394 provider_host->GetWindowClientInfo(callback); |
| 395 return; |
| 396 } |
| 397 |
| 398 DCHECK(provider_host->client_type() == |
| 399 blink::WebServiceWorkerClientTypeWorker || |
| 400 provider_host->client_type() == |
| 401 blink::WebServiceWorkerClientTypeSharedWorker); |
| 402 |
| 403 ServiceWorkerClientInfo client_info( |
| 404 provider_host->client_uuid(), blink::WebPageVisibilityStateHidden, |
| 405 false, // is_focused |
| 406 provider_host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, |
| 407 base::TimeTicks(), provider_host->client_type()); |
| 408 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 409 base::Bind(callback, client_info)); |
| 410 } |
| 411 |
374 void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller, | 412 void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
375 const ServiceWorkerClientQueryOptions& options, | 413 const ServiceWorkerClientQueryOptions& options, |
376 const ClientsCallback& callback) { | 414 const ClientsCallback& callback) { |
377 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 415 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
378 | 416 |
379 ServiceWorkerClients clients; | 417 ServiceWorkerClients clients; |
380 if (!controller->HasControllee() && !options.include_uncontrolled) { | 418 if (!controller->HasControllee() && !options.include_uncontrolled) { |
381 DidGetClients(callback, &clients); | 419 DidGetClients(callback, &clients); |
382 return; | 420 return; |
383 } | 421 } |
384 | 422 |
385 // For Window clients we want to query the info on the UI thread first. | 423 // For Window clients we want to query the info on the UI thread first. |
386 if (options.client_type == blink::WebServiceWorkerClientTypeWindow || | 424 if (options.client_type == blink::WebServiceWorkerClientTypeWindow || |
387 options.client_type == blink::WebServiceWorkerClientTypeAll) { | 425 options.client_type == blink::WebServiceWorkerClientTypeAll) { |
388 GetWindowClients(controller, options, callback); | 426 GetWindowClients(controller, options, callback); |
389 return; | 427 return; |
390 } | 428 } |
391 | 429 |
392 GetNonWindowClients(controller, options, &clients); | 430 GetNonWindowClients(controller, options, &clients); |
393 DidGetClients(callback, &clients); | 431 DidGetClients(callback, &clients); |
394 } | 432 } |
395 | 433 |
396 } // namespace service_worker_client_utils | 434 } // namespace service_worker_client_utils |
397 } // namespace content | 435 } // namespace content |
OLD | NEW |