Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_version.h" | 5 #include "content/browser/service_worker/service_worker_version.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 #include "content/public/browser/web_contents_observer.h" | 32 #include "content/public/browser/web_contents_observer.h" |
| 33 #include "content/public/common/child_process_host.h" | 33 #include "content/public/common/child_process_host.h" |
| 34 #include "content/public/common/content_client.h" | 34 #include "content/public/common/content_client.h" |
| 35 #include "content/public/common/content_switches.h" | 35 #include "content/public/common/content_switches.h" |
| 36 #include "content/public/common/result_codes.h" | 36 #include "content/public/common/result_codes.h" |
| 37 #include "net/http/http_response_info.h" | 37 #include "net/http/http_response_info.h" |
| 38 | 38 |
| 39 namespace content { | 39 namespace content { |
| 40 | 40 |
| 41 using StatusCallback = ServiceWorkerVersion::StatusCallback; | 41 using StatusCallback = ServiceWorkerVersion::StatusCallback; |
| 42 using ServiceWorkerClients = std::vector<ServiceWorkerClientInfo>; | |
| 42 using GetClientsCallback = | 43 using GetClientsCallback = |
| 43 base::Callback<void(const std::vector<ServiceWorkerClientInfo>&)>; | 44 base::Callback<void(scoped_ptr<ServiceWorkerClients>)>; |
| 44 | 45 |
| 45 namespace { | 46 namespace { |
| 46 | 47 |
| 47 // Delay between the timeout timer firing. | 48 // Delay between the timeout timer firing. |
| 48 const int kTimeoutTimerDelaySeconds = 30; | 49 const int kTimeoutTimerDelaySeconds = 30; |
| 49 | 50 |
| 50 // Time to wait until stopping an idle worker. | 51 // Time to wait until stopping an idle worker. |
| 51 const int kIdleWorkerTimeoutSeconds = 30; | 52 const int kIdleWorkerTimeoutSeconds = 30; |
| 52 | 53 |
| 53 // Default delay for scheduled update. | 54 // Default delay for scheduled update. |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 void RestartTick(base::TimeTicks* time) { | 276 void RestartTick(base::TimeTicks* time) { |
| 276 *time = base::TimeTicks().Now(); | 277 *time = base::TimeTicks().Now(); |
| 277 } | 278 } |
| 278 | 279 |
| 279 base::TimeDelta GetTickDuration(const base::TimeTicks& time) { | 280 base::TimeDelta GetTickDuration(const base::TimeTicks& time) { |
| 280 if (time.is_null()) | 281 if (time.is_null()) |
| 281 return base::TimeDelta(); | 282 return base::TimeDelta(); |
| 282 return base::TimeTicks().Now() - time; | 283 return base::TimeTicks().Now() - time; |
| 283 } | 284 } |
| 284 | 285 |
| 285 void OnGetClientsFromUI( | 286 void OnGetWindowClientsFromUI( |
| 286 // The tuple contains process_id, frame_id, client_uuid. | 287 // The tuple contains process_id, frame_id, client_uuid. |
| 287 const std::vector<Tuple<int,int,std::string>>& clients_info, | 288 const std::vector<Tuple<int, int, std::string>>& clients_info, |
| 288 const GURL& script_url, | 289 const GURL& script_url, |
| 289 const GetClientsCallback& callback) { | 290 const GetClientsCallback& callback) { |
| 290 std::vector<ServiceWorkerClientInfo> clients; | 291 scoped_ptr<ServiceWorkerClients> clients(new ServiceWorkerClients); |
| 291 | 292 |
| 292 for (const auto& it : clients_info) { | 293 for (const auto& it : clients_info) { |
| 293 ServiceWorkerClientInfo info = | 294 ServiceWorkerClientInfo info = |
| 294 ServiceWorkerProviderHost::GetClientInfoOnUI(get<0>(it), get<1>(it)); | 295 ServiceWorkerProviderHost::GetWindowClientInfoOnUI(get<0>(it), |
| 296 get<1>(it)); | |
| 295 | 297 |
| 296 // If the request to the provider_host returned an empty | 298 // If the request to the provider_host returned an empty |
| 297 // ServiceWorkerClientInfo, that means that it wasn't possible to associate | 299 // ServiceWorkerClientInfo, that means that it wasn't possible to associate |
| 298 // it with a valid RenderFrameHost. It might be because the frame was killed | 300 // it with a valid RenderFrameHost. It might be because the frame was killed |
| 299 // or navigated in between. | 301 // or navigated in between. |
| 300 if (info.IsEmpty()) | 302 if (info.IsEmpty()) |
| 301 continue; | 303 continue; |
| 302 | 304 |
| 303 // We can get info for a frame that was navigating end ended up with a | 305 // We can get info for a frame that was navigating end ended up with a |
| 304 // different URL than expected. In such case, we should make sure to not | 306 // different URL than expected. In such case, we should make sure to not |
| 305 // expose cross-origin WindowClient. | 307 // expose cross-origin WindowClient. |
| 306 if (info.url.GetOrigin() != script_url.GetOrigin()) | 308 if (info.url.GetOrigin() != script_url.GetOrigin()) |
| 307 return; | 309 continue; |
|
nhiroki
2015/03/31 05:26:33
Oh... |callback| was gone... good catch!
| |
| 308 | 310 |
| 309 info.client_uuid = get<2>(it); | 311 info.client_uuid = get<2>(it); |
| 310 clients.push_back(info); | 312 clients->push_back(info); |
| 311 } | 313 } |
| 312 | 314 |
| 313 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 315 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 314 base::Bind(callback, clients)); | 316 base::Bind(callback, base::Passed(&clients))); |
| 317 } | |
| 318 | |
| 319 void AddWindowClient(ServiceWorkerProviderHost* host, | |
| 320 std::vector<Tuple<int, int, std::string>>* client_info) { | |
| 321 if (host->client_type() != blink::WebServiceWorkerClientTypeWindow) | |
| 322 return; | |
| 323 client_info->push_back( | |
| 324 MakeTuple(host->process_id(), host->frame_id(), host->client_uuid())); | |
| 325 } | |
| 326 | |
| 327 void AddNonWindowClient(ServiceWorkerProviderHost* host, | |
| 328 const ServiceWorkerClientQueryOptions& options, | |
| 329 ServiceWorkerClients* clients) { | |
| 330 blink::WebServiceWorkerClientType host_client_type = host->client_type(); | |
| 331 if (host_client_type == blink::WebServiceWorkerClientTypeWindow) | |
| 332 return; | |
| 333 if (options.client_type != blink::WebServiceWorkerClientTypeAll && | |
| 334 options.client_type != host_client_type) | |
| 335 return; | |
| 336 | |
| 337 ServiceWorkerClientInfo client_info( | |
| 338 blink::WebPageVisibilityStateHidden, | |
| 339 false, // is_focused | |
| 340 host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, host_client_type); | |
| 341 client_info.client_uuid = host->client_uuid(); | |
| 342 clients->push_back(client_info); | |
| 315 } | 343 } |
| 316 | 344 |
| 317 } // namespace | 345 } // namespace |
| 318 | 346 |
| 319 const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5; | 347 const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5; |
| 320 const int ServiceWorkerVersion::kRequestTimeoutMinutes = 5; | 348 const int ServiceWorkerVersion::kRequestTimeoutMinutes = 5; |
| 321 | 349 |
| 322 ServiceWorkerVersion::ServiceWorkerVersion( | 350 ServiceWorkerVersion::ServiceWorkerVersion( |
| 323 ServiceWorkerRegistration* registration, | 351 ServiceWorkerRegistration* registration, |
| 324 const GURL& script_url, | 352 const GURL& script_url, |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1030 const ServiceWorkerClientQueryOptions& options) { | 1058 const ServiceWorkerClientQueryOptions& options) { |
| 1031 if (controllee_map_.empty() && !options.include_uncontrolled) { | 1059 if (controllee_map_.empty() && !options.include_uncontrolled) { |
| 1032 if (running_status() == RUNNING) { | 1060 if (running_status() == RUNNING) { |
| 1033 embedded_worker_->SendMessage( | 1061 embedded_worker_->SendMessage( |
| 1034 ServiceWorkerMsg_DidGetClients(request_id, | 1062 ServiceWorkerMsg_DidGetClients(request_id, |
| 1035 std::vector<ServiceWorkerClientInfo>())); | 1063 std::vector<ServiceWorkerClientInfo>())); |
| 1036 } | 1064 } |
| 1037 return; | 1065 return; |
| 1038 } | 1066 } |
| 1039 | 1067 |
| 1040 TRACE_EVENT0("ServiceWorker", | 1068 // For Window clients we want to query the info on the UI thread first. |
| 1041 "ServiceWorkerVersion::OnGetClients"); | 1069 if (options.client_type == blink::WebServiceWorkerClientTypeWindow || |
| 1042 | 1070 options.client_type == blink::WebServiceWorkerClientTypeAll) { |
| 1043 // 4.3.1 matchAll(options) | 1071 GetWindowClients(request_id, options); |
| 1044 std::vector<Tuple<int,int,std::string>> clients_info; | 1072 return; |
| 1045 if (!options.include_uncontrolled) { | |
| 1046 for (auto& controllee : controllee_map_) { | |
| 1047 int process_id = controllee.second->process_id(); | |
| 1048 int frame_id = controllee.second->frame_id(); | |
| 1049 const std::string& client_uuid = controllee.first; | |
| 1050 clients_info.push_back(MakeTuple(process_id, frame_id, client_uuid)); | |
| 1051 } | |
| 1052 } else { | |
| 1053 for (auto it = | |
| 1054 context_->GetClientProviderHostIterator(script_url_.GetOrigin()); | |
| 1055 !it->IsAtEnd(); it->Advance()) { | |
| 1056 ServiceWorkerProviderHost* host = it->GetProviderHost(); | |
| 1057 clients_info.push_back( | |
| 1058 MakeTuple(host->process_id(), host->frame_id(), host->client_uuid())); | |
| 1059 } | |
| 1060 } | 1073 } |
| 1061 | 1074 |
| 1062 BrowserThread::PostTask( | 1075 ServiceWorkerClients clients; |
| 1063 BrowserThread::UI, FROM_HERE, | 1076 GetNonWindowClients(request_id, options, &clients); |
| 1064 base::Bind(&OnGetClientsFromUI, clients_info, script_url_, | 1077 embedded_worker_->SendMessage( |
| 1065 base::Bind(&ServiceWorkerVersion::DidGetClients, | 1078 ServiceWorkerMsg_DidGetClients(request_id, clients)); |
| 1066 weak_factory_.GetWeakPtr(), | |
| 1067 request_id))); | |
| 1068 | |
| 1069 } | 1079 } |
| 1070 | 1080 |
| 1071 void ServiceWorkerVersion::OnActivateEventFinished( | 1081 void ServiceWorkerVersion::OnActivateEventFinished( |
| 1072 int request_id, | 1082 int request_id, |
| 1073 blink::WebServiceWorkerEventResult result) { | 1083 blink::WebServiceWorkerEventResult result) { |
| 1074 DCHECK(ACTIVATING == status() || | 1084 DCHECK(ACTIVATING == status() || |
| 1075 REDUNDANT == status()) << status(); | 1085 REDUNDANT == status()) << status(); |
| 1076 TRACE_EVENT0("ServiceWorker", | 1086 TRACE_EVENT0("ServiceWorker", |
| 1077 "ServiceWorkerVersion::OnActivateEventFinished"); | 1087 "ServiceWorkerVersion::OnActivateEventFinished"); |
| 1078 | 1088 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1277 } | 1287 } |
| 1278 | 1288 |
| 1279 for (auto it = | 1289 for (auto it = |
| 1280 context_->GetClientProviderHostIterator(script_url_.GetOrigin()); | 1290 context_->GetClientProviderHostIterator(script_url_.GetOrigin()); |
| 1281 !it->IsAtEnd(); it->Advance()) { | 1291 !it->IsAtEnd(); it->Advance()) { |
| 1282 ServiceWorkerProviderHost* provider_host = it->GetProviderHost(); | 1292 ServiceWorkerProviderHost* provider_host = it->GetProviderHost(); |
| 1283 if (provider_host->process_id() != render_process_id || | 1293 if (provider_host->process_id() != render_process_id || |
| 1284 provider_host->frame_id() != render_frame_id) { | 1294 provider_host->frame_id() != render_frame_id) { |
| 1285 continue; | 1295 continue; |
| 1286 } | 1296 } |
| 1287 provider_host->GetClientInfo(base::Bind( | 1297 provider_host->GetWindowClientInfo(base::Bind( |
| 1288 &ServiceWorkerVersion::OnOpenWindowFinished, weak_factory_.GetWeakPtr(), | 1298 &ServiceWorkerVersion::OnOpenWindowFinished, weak_factory_.GetWeakPtr(), |
| 1289 request_id, provider_host->client_uuid())); | 1299 request_id, provider_host->client_uuid())); |
| 1290 return; | 1300 return; |
| 1291 } | 1301 } |
| 1292 | 1302 |
| 1293 // If here, it means that no provider_host was found, in which case, the | 1303 // If here, it means that no provider_host was found, in which case, the |
| 1294 // renderer should still be informed that the window was opened. | 1304 // renderer should still be informed that the window was opened. |
| 1295 OnOpenWindowFinished(request_id, std::string(), ServiceWorkerClientInfo()); | 1305 OnOpenWindowFinished(request_id, std::string(), ServiceWorkerClientInfo()); |
| 1296 } | 1306 } |
| 1297 | 1307 |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1498 if (!timeout_timer_.IsRunning()) | 1508 if (!timeout_timer_.IsRunning()) |
| 1499 StartTimeoutTimer(); | 1509 StartTimeoutTimer(); |
| 1500 if (running_status() == STOPPED) { | 1510 if (running_status() == STOPPED) { |
| 1501 embedded_worker_->Start( | 1511 embedded_worker_->Start( |
| 1502 version_id_, scope_, script_url_, pause_after_download, | 1512 version_id_, scope_, script_url_, pause_after_download, |
| 1503 base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated, | 1513 base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated, |
| 1504 weak_factory_.GetWeakPtr())); | 1514 weak_factory_.GetWeakPtr())); |
| 1505 } | 1515 } |
| 1506 } | 1516 } |
| 1507 | 1517 |
| 1508 void ServiceWorkerVersion::DidGetClients( | 1518 void ServiceWorkerVersion::GetWindowClients( |
| 1509 int request_id, | 1519 int request_id, |
| 1510 const std::vector<ServiceWorkerClientInfo>& clients) { | 1520 const ServiceWorkerClientQueryOptions& options) { |
| 1521 DCHECK(options.client_type == blink::WebServiceWorkerClientTypeWindow || | |
| 1522 options.client_type == blink::WebServiceWorkerClientTypeAll); | |
| 1523 TRACE_EVENT0("ServiceWorker", "ServiceWorkerVersion::GetWindowClients"); | |
|
falken
2015/03/31 03:39:48
Should this trace span to DidGetWindowClients?
nhiroki
2015/04/01 00:50:53
Done in https://codereview.chromium.org/1050733002
| |
| 1524 | |
| 1525 // 4.3.1 matchAll(options) | |
|
falken
2015/03/31 03:39:48
FYI I've given up on putting spec section numbers
nhiroki
2015/04/01 00:50:53
Done in https://codereview.chromium.org/1050733002
| |
| 1526 std::vector<Tuple<int, int, std::string>> clients_info; | |
| 1527 if (!options.include_uncontrolled) { | |
| 1528 for (auto& controllee : controllee_map_) | |
| 1529 AddWindowClient(controllee.second, &clients_info); | |
| 1530 } else { | |
| 1531 for (auto it = | |
| 1532 context_->GetClientProviderHostIterator(script_url_.GetOrigin()); | |
| 1533 !it->IsAtEnd(); it->Advance()) { | |
| 1534 AddWindowClient(it->GetProviderHost(), &clients_info); | |
| 1535 } | |
| 1536 } | |
| 1537 | |
| 1538 if (clients_info.empty()) { | |
| 1539 DidGetWindowClients(request_id, options, | |
| 1540 make_scoped_ptr(new ServiceWorkerClients)); | |
| 1541 return; | |
| 1542 } | |
| 1543 | |
| 1544 BrowserThread::PostTask( | |
| 1545 BrowserThread::UI, FROM_HERE, | |
| 1546 base::Bind(&OnGetWindowClientsFromUI, clients_info, script_url_, | |
| 1547 base::Bind(&ServiceWorkerVersion::DidGetWindowClients, | |
| 1548 weak_factory_.GetWeakPtr(), request_id, options))); | |
| 1549 } | |
| 1550 | |
| 1551 void ServiceWorkerVersion::DidGetWindowClients( | |
| 1552 int request_id, | |
| 1553 const ServiceWorkerClientQueryOptions& options, | |
| 1554 scoped_ptr<ServiceWorkerClients> clients) { | |
| 1511 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1555 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1512 if (running_status() != RUNNING) | 1556 if (running_status() != RUNNING) |
| 1513 return; | 1557 return; |
| 1514 | 1558 |
| 1559 if (options.client_type == blink::WebServiceWorkerClientTypeAll) | |
| 1560 GetNonWindowClients(request_id, options, clients.get()); | |
| 1561 | |
| 1515 embedded_worker_->SendMessage( | 1562 embedded_worker_->SendMessage( |
| 1516 ServiceWorkerMsg_DidGetClients(request_id, clients)); | 1563 ServiceWorkerMsg_DidGetClients(request_id, *clients)); |
| 1564 } | |
| 1565 | |
| 1566 void ServiceWorkerVersion::GetNonWindowClients( | |
| 1567 int request_id, | |
| 1568 const ServiceWorkerClientQueryOptions& options, | |
| 1569 ServiceWorkerClients* clients) { | |
| 1570 if (!options.include_uncontrolled) { | |
| 1571 for (auto& controllee : controllee_map_) { | |
| 1572 AddNonWindowClient(controllee.second, options, clients); | |
| 1573 } | |
| 1574 } else { | |
| 1575 for (auto it = | |
| 1576 context_->GetClientProviderHostIterator(script_url_.GetOrigin()); | |
| 1577 !it->IsAtEnd(); it->Advance()) { | |
| 1578 AddNonWindowClient(it->GetProviderHost(), options, clients); | |
| 1579 } | |
| 1580 } | |
| 1517 } | 1581 } |
| 1518 | 1582 |
| 1519 void ServiceWorkerVersion::StartTimeoutTimer() { | 1583 void ServiceWorkerVersion::StartTimeoutTimer() { |
| 1520 DCHECK(!timeout_timer_.IsRunning()); | 1584 DCHECK(!timeout_timer_.IsRunning()); |
| 1521 | 1585 |
| 1522 if (embedded_worker_->devtools_attached()) { | 1586 if (embedded_worker_->devtools_attached()) { |
| 1523 // Don't record the startup time metric once DevTools is attached. | 1587 // Don't record the startup time metric once DevTools is attached. |
| 1524 ClearTick(&start_time_); | 1588 ClearTick(&start_time_); |
| 1525 skip_recording_startup_time_ = true; | 1589 skip_recording_startup_time_ = true; |
| 1526 } else { | 1590 } else { |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1761 while (!requests_.empty()) { | 1825 while (!requests_.empty()) { |
| 1762 RequestInfo info = requests_.front(); | 1826 RequestInfo info = requests_.front(); |
| 1763 info.time = ticks; | 1827 info.time = ticks; |
| 1764 new_requests.push(info); | 1828 new_requests.push(info); |
| 1765 requests_.pop(); | 1829 requests_.pop(); |
| 1766 } | 1830 } |
| 1767 requests_ = new_requests; | 1831 requests_ = new_requests; |
| 1768 } | 1832 } |
| 1769 | 1833 |
| 1770 } // namespace content | 1834 } // namespace content |
| OLD | NEW |