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 |