Chromium Code Reviews| 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 void AddNonWindowClient(ServiceWorkerProviderHost* host, | 218 void AddNonWindowClient(ServiceWorkerProviderHost* host, |
| 219 const ServiceWorkerClientQueryOptions& options, | 219 const ServiceWorkerClientQueryOptions& options, |
| 220 ServiceWorkerClients* clients) { | 220 ServiceWorkerClients* clients) { |
| 221 blink::WebServiceWorkerClientType host_client_type = host->client_type(); | 221 blink::WebServiceWorkerClientType host_client_type = host->client_type(); |
| 222 if (host_client_type == blink::WebServiceWorkerClientTypeWindow) | 222 if (host_client_type == blink::WebServiceWorkerClientTypeWindow) |
| 223 return; | 223 return; |
| 224 if (options.client_type != blink::WebServiceWorkerClientTypeAll && | 224 if (options.client_type != blink::WebServiceWorkerClientTypeAll && |
| 225 options.client_type != host_client_type) | 225 options.client_type != host_client_type) |
| 226 return; | 226 return; |
| 227 | 227 |
| 228 ServiceWorkerClientInfo client_info(blink::WebPageVisibilityStateHidden, | 228 ServiceWorkerClientInfo client_info( |
| 229 false, // is_focused | 229 host->client_uuid(), blink::WebPageVisibilityStateHidden, |
| 230 host->document_url(), | 230 false, // is_focused |
| 231 REQUEST_CONTEXT_FRAME_TYPE_NONE, | 231 host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, base::TimeTicks(), |
| 232 base::TimeTicks(), host_client_type); | 232 host_client_type); |
| 233 client_info.client_uuid = host->client_uuid(); | |
| 234 clients->push_back(client_info); | 233 clients->push_back(client_info); |
| 235 } | 234 } |
| 235 void OnGetWindowClientOnUI( | |
|
nhiroki
2016/02/16 06:09:31
nit: please insert a blank line before this line.
jungkees
2016/02/16 16:28:58
Done.
| |
| 236 const base::Tuple<int, int, std::string>& client_info, | |
|
nhiroki
2016/02/16 06:09:31
Is this necessary to be a Tuple? Can we separate t
jungkees
2016/02/16 16:28:58
I was just trying to align it to |clients_info| pa
| |
| 237 const GURL& script_url, | |
| 238 const ServiceWorkerProviderHost::GetClientInfoCallback& callback) { | |
|
nhiroki
2016/02/16 06:09:31
Can you add DCHECK_CURRENTLY_ON(BrowserThread::UI)
jungkees
2016/02/16 16:28:58
Done.
| |
| 239 ServiceWorkerClientInfo info = | |
| 240 ServiceWorkerProviderHost::GetWindowClientInfoOnUI( | |
| 241 base::get<0>(client_info), base::get<1>(client_info), | |
| 242 base::get<2>(client_info)); | |
| 243 | |
| 244 if (info.url.GetOrigin() != script_url.GetOrigin()) | |
| 245 info = ServiceWorkerClientInfo(); | |
| 246 | |
| 247 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 248 base::Bind(callback, info)); | |
| 249 } | |
| 236 | 250 |
| 237 void OnGetWindowClientsOnUI( | 251 void OnGetWindowClientsOnUI( |
| 238 // The tuple contains process_id, frame_id, client_uuid. | 252 // The tuple contains process_id, frame_id, client_uuid. |
| 239 const std::vector<base::Tuple<int, int, std::string>>& clients_info, | 253 const std::vector<base::Tuple<int, int, std::string>>& clients_info, |
| 240 const GURL& script_url, | 254 const GURL& script_url, |
| 241 const GetWindowClientsCallback& callback) { | 255 const GetWindowClientsCallback& callback) { |
| 242 scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients); | 256 scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients); |
| 243 | 257 |
| 244 for (const auto& it : clients_info) { | 258 for (const auto& it : clients_info) { |
| 245 ServiceWorkerClientInfo info = | 259 ServiceWorkerClientInfo info = |
| 246 ServiceWorkerProviderHost::GetWindowClientInfoOnUI(base::get<0>(it), | 260 ServiceWorkerProviderHost::GetWindowClientInfoOnUI( |
| 247 base::get<1>(it)); | 261 base::get<0>(it), base::get<1>(it), base::get<2>(it)); |
| 248 | 262 |
| 249 // If the request to the provider_host returned an empty | 263 // If the request to the provider_host returned an empty |
| 250 // ServiceWorkerClientInfo, that means that it wasn't possible to associate | 264 // ServiceWorkerClientInfo, that means that it wasn't possible to associate |
| 251 // it with a valid RenderFrameHost. It might be because the frame was killed | 265 // it with a valid RenderFrameHost. It might be because the frame was killed |
| 252 // or navigated in between. | 266 // or navigated in between. |
| 253 if (info.IsEmpty()) | 267 if (info.IsEmpty()) |
| 254 continue; | 268 continue; |
| 255 | 269 |
| 256 // We can get info for a frame that was navigating end ended up with a | 270 // 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 | 271 // different URL than expected. In such case, we should make sure to not |
| 258 // expose cross-origin WindowClient. | 272 // expose cross-origin WindowClient. |
| 259 if (info.url.GetOrigin() != script_url.GetOrigin()) | 273 if (info.url.GetOrigin() != script_url.GetOrigin()) |
| 260 continue; | 274 continue; |
| 261 | 275 |
| 262 info.client_uuid = base::get<2>(it); | |
| 263 clients->push_back(info); | 276 clients->push_back(info); |
| 264 } | 277 } |
| 265 | 278 |
| 266 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 279 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 267 base::Bind(callback, base::Passed(&clients))); | 280 base::Bind(callback, base::Passed(&clients))); |
| 268 } | 281 } |
| 269 | 282 |
| 270 struct ServiceWorkerClientInfoSortMRU { | 283 struct ServiceWorkerClientInfoSortMRU { |
| 271 bool operator()(const ServiceWorkerClientInfo& a, | 284 bool operator()(const ServiceWorkerClientInfo& a, |
| 272 const ServiceWorkerClientInfo& b) const { | 285 const ServiceWorkerClientInfo& b) const { |
| 273 return a.last_focus_time > b.last_focus_time; | 286 return a.last_focus_time > b.last_focus_time; |
| 274 } | 287 } |
| 275 }; | 288 }; |
| 276 | 289 |
| 290 void DidGetClient( | |
| 291 const ServiceWorkerProviderHost::GetClientInfoCallback& callback, | |
| 292 const ServiceWorkerClientInfo& client_info) { | |
| 293 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 294 | |
| 295 callback.Run(client_info); | |
| 296 } | |
| 297 | |
| 277 void DidGetClients(const ClientsCallback& callback, | 298 void DidGetClients(const ClientsCallback& callback, |
| 278 ServiceWorkerClients* clients) { | 299 ServiceWorkerClients* clients) { |
| 279 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 300 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 280 | 301 |
| 281 // Sort clients so that the most recently active tab is in the front. | 302 // Sort clients so that the most recently active tab is in the front. |
| 282 std::sort(clients->begin(), clients->end(), ServiceWorkerClientInfoSortMRU()); | 303 std::sort(clients->begin(), clients->end(), ServiceWorkerClientInfoSortMRU()); |
| 283 | 304 |
| 284 callback.Run(clients); | 305 callback.Run(clients); |
| 285 } | 306 } |
| 286 | 307 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 const base::WeakPtr<ServiceWorkerContextCore>& context, | 385 const base::WeakPtr<ServiceWorkerContextCore>& context, |
| 365 const NavigationCallback& callback) { | 386 const NavigationCallback& callback) { |
| 366 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 387 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 367 BrowserThread::PostTask( | 388 BrowserThread::PostTask( |
| 368 BrowserThread::UI, FROM_HERE, | 389 BrowserThread::UI, FROM_HERE, |
| 369 base::Bind( | 390 base::Bind( |
| 370 &NavigateClientOnUI, url, script_url, process_id, frame_id, | 391 &NavigateClientOnUI, url, script_url, process_id, frame_id, |
| 371 base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback))); | 392 base::Bind(&DidNavigate, context, script_url.GetOrigin(), callback))); |
| 372 } | 393 } |
| 373 | 394 |
| 395 void GetClient( | |
| 396 const base::WeakPtr<ServiceWorkerVersion>& controller, | |
| 397 const std::string& client_uuid, | |
| 398 const base::WeakPtr<ServiceWorkerContextCore>& context, | |
| 399 const ServiceWorkerProviderHost::GetClientInfoCallback& callback) { | |
| 400 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 401 | |
| 402 ServiceWorkerProviderHost* provider_host = | |
| 403 context->GetProviderHostByClientID(client_uuid); | |
| 404 | |
| 405 if (!provider_host) { | |
| 406 // The client may already have been closed, just ignore. | |
| 407 DidGetClient(callback, ServiceWorkerClientInfo()); | |
|
nhiroki
2016/02/16 06:09:31
GetClient() sometimes calls the callback synchrono
jungkees
2016/02/16 16:28:58
Thanks for the good point. Addressed.
| |
| 408 return; | |
| 409 } | |
| 410 | |
| 411 if (provider_host->client_type() == blink::WebServiceWorkerClientTypeWindow) { | |
| 412 BrowserThread::PostTask( | |
| 413 BrowserThread::UI, FROM_HERE, | |
| 414 base::Bind(&OnGetWindowClientOnUI, | |
| 415 base::MakeTuple(provider_host->process_id(), | |
| 416 provider_host->frame_id(), | |
| 417 provider_host->client_uuid()), | |
| 418 controller->script_url(), base::Bind(callback))); | |
|
nhiroki
2016/02/16 06:09:31
If you don't call DidGetClient in this async case,
jungkees
2016/02/16 16:28:58
Agreed to this point. Removed DidGetClient and rep
| |
| 419 return; | |
| 420 } | |
| 421 | |
| 422 if (provider_host->document_url().GetOrigin() != | |
| 423 controller->script_url().GetOrigin()) { | |
| 424 DidGetClient(callback, ServiceWorkerClientInfo()); | |
|
nhiroki
2016/02/16 06:09:31
ditto: sync call vs. async call
jungkees
2016/02/16 16:28:58
Done.
| |
| 425 return; | |
| 426 } | |
| 427 | |
| 428 ServiceWorkerClientInfo client_info( | |
| 429 provider_host->client_uuid(), blink::WebPageVisibilityStateHidden, | |
| 430 false, // is_focused | |
| 431 provider_host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, | |
| 432 base::TimeTicks(), provider_host->client_type()); | |
| 433 DidGetClient(callback, client_info); | |
|
nhiroki
2016/02/16 06:09:31
ditto: sync call vs. async call
jungkees
2016/02/16 16:28:58
Done.
| |
| 434 } | |
| 435 | |
| 374 void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller, | 436 void GetClients(const base::WeakPtr<ServiceWorkerVersion>& controller, |
| 375 const ServiceWorkerClientQueryOptions& options, | 437 const ServiceWorkerClientQueryOptions& options, |
| 376 const ClientsCallback& callback) { | 438 const ClientsCallback& callback) { |
| 377 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 439 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 378 | 440 |
| 379 ServiceWorkerClients clients; | 441 ServiceWorkerClients clients; |
| 380 if (!controller->HasControllee() && !options.include_uncontrolled) { | 442 if (!controller->HasControllee() && !options.include_uncontrolled) { |
| 381 DidGetClients(callback, &clients); | 443 DidGetClients(callback, &clients); |
| 382 return; | 444 return; |
| 383 } | 445 } |
| 384 | 446 |
| 385 // For Window clients we want to query the info on the UI thread first. | 447 // For Window clients we want to query the info on the UI thread first. |
| 386 if (options.client_type == blink::WebServiceWorkerClientTypeWindow || | 448 if (options.client_type == blink::WebServiceWorkerClientTypeWindow || |
| 387 options.client_type == blink::WebServiceWorkerClientTypeAll) { | 449 options.client_type == blink::WebServiceWorkerClientTypeAll) { |
| 388 GetWindowClients(controller, options, callback); | 450 GetWindowClients(controller, options, callback); |
| 389 return; | 451 return; |
| 390 } | 452 } |
| 391 | 453 |
| 392 GetNonWindowClients(controller, options, &clients); | 454 GetNonWindowClients(controller, options, &clients); |
| 393 DidGetClients(callback, &clients); | 455 DidGetClients(callback, &clients); |
| 394 } | 456 } |
| 395 | 457 |
| 396 } // namespace service_worker_client_utils | 458 } // namespace service_worker_client_utils |
| 397 } // namespace content | 459 } // namespace content |
| OLD | NEW |