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 19 matching lines...) Expand all Loading... | |
| 30 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
| 31 #include "content/public/browser/web_contents_observer.h" | 31 #include "content/public/browser/web_contents_observer.h" |
| 32 #include "content/public/common/child_process_host.h" | 32 #include "content/public/common/child_process_host.h" |
| 33 #include "content/public/common/content_client.h" | 33 #include "content/public/common/content_client.h" |
| 34 #include "content/public/common/content_switches.h" | 34 #include "content/public/common/content_switches.h" |
| 35 #include "content/public/common/result_codes.h" | 35 #include "content/public/common/result_codes.h" |
| 36 #include "net/http/http_response_info.h" | 36 #include "net/http/http_response_info.h" |
| 37 | 37 |
| 38 namespace content { | 38 namespace content { |
| 39 | 39 |
| 40 typedef ServiceWorkerVersion::StatusCallback StatusCallback; | 40 using StatusCallback = ServiceWorkerVersion::StatusCallback; |
| 41 | 41 using GetClientDocumentsCallback = |
| 42 class ServiceWorkerVersion::GetClientDocumentsCallback | 42 base::Callback<void(const std::vector<ServiceWorkerClientInfo>&)>; |
| 43 : public base::RefCounted<GetClientDocumentsCallback> { | |
| 44 public: | |
| 45 GetClientDocumentsCallback(int request_id, | |
| 46 ServiceWorkerVersion* version) | |
| 47 : request_id_(request_id), | |
| 48 version_(version) { | |
| 49 DCHECK(version_); | |
| 50 } | |
| 51 | |
| 52 void AddClientInfo(int client_id, const ServiceWorkerClientInfo& info) { | |
| 53 clients_.push_back(info); | |
| 54 clients_.back().client_id = client_id; | |
| 55 } | |
| 56 | |
| 57 private: | |
| 58 friend class base::RefCounted<GetClientDocumentsCallback>; | |
| 59 | |
| 60 virtual ~GetClientDocumentsCallback() { | |
| 61 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 62 | |
| 63 if (version_->running_status() == RUNNING) { | |
| 64 version_->embedded_worker_->SendMessage( | |
| 65 ServiceWorkerMsg_DidGetClientDocuments(request_id_, clients_)); | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 std::vector<ServiceWorkerClientInfo> clients_; | |
| 70 int request_id_; | |
| 71 scoped_refptr<ServiceWorkerVersion> version_; | |
| 72 | |
| 73 DISALLOW_COPY_AND_ASSIGN(GetClientDocumentsCallback); | |
| 74 }; | |
| 75 | 43 |
| 76 namespace { | 44 namespace { |
| 77 | 45 |
| 78 // Delay between the timeout timer firing. | 46 // Delay between the timeout timer firing. |
| 79 const int kTimeoutTimerDelaySeconds = 30; | 47 const int kTimeoutTimerDelaySeconds = 30; |
| 80 | 48 |
| 81 // Time to wait until stopping an idle worker. | 49 // Time to wait until stopping an idle worker. |
| 82 const int kIdleWorkerTimeoutSeconds = 30; | 50 const int kIdleWorkerTimeoutSeconds = 30; |
| 83 | 51 |
| 84 // Default delay for scheduled update. | 52 // Default delay for scheduled update. |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 void RestartTick(base::TimeTicks* time) { | 247 void RestartTick(base::TimeTicks* time) { |
| 280 *time = base::TimeTicks().Now(); | 248 *time = base::TimeTicks().Now(); |
| 281 } | 249 } |
| 282 | 250 |
| 283 base::TimeDelta GetTickDuration(const base::TimeTicks& time) { | 251 base::TimeDelta GetTickDuration(const base::TimeTicks& time) { |
| 284 if (time.is_null()) | 252 if (time.is_null()) |
| 285 return base::TimeDelta(); | 253 return base::TimeDelta(); |
| 286 return base::TimeTicks().Now() - time; | 254 return base::TimeTicks().Now() - time; |
| 287 } | 255 } |
| 288 | 256 |
| 257 void OnGetClientDocumentsFromUI( | |
| 258 // The tuple contains process_id, frame_id, client_id. | |
|
michaeln
2015/03/06 23:55:22
nice comment
| |
| 259 const std::vector<Tuple<int,int,int>>& clients_info, | |
| 260 const GURL& script_url, | |
| 261 const GetClientDocumentsCallback& callback) { | |
| 262 std::vector<ServiceWorkerClientInfo> clients; | |
| 263 | |
| 264 for (const auto& it : clients_info) { | |
| 265 ServiceWorkerClientInfo info = | |
| 266 ServiceWorkerProviderHost::GetClientInfoOnUI(get<0>(it), get<1>(it)); | |
| 267 | |
| 268 // If the request to the provider_host returned an empty | |
| 269 // ServiceWorkerClientInfo, that means that it wasn't possible to associate | |
| 270 // it with a valid RenderFrameHost. It might be because the frame was killed | |
| 271 // or navigated in between. | |
| 272 if (info.IsEmpty()) | |
| 273 continue; | |
| 274 | |
| 275 // We can get info for a frame that was navigating end ended up with a | |
| 276 // different URL than expected. In such case, we should make sure to not | |
| 277 // expose cross-origin WindowClient. | |
| 278 if (info.url.GetOrigin() != script_url.GetOrigin()) | |
| 279 return; | |
| 280 | |
| 281 info.client_id = get<2>(it); | |
| 282 clients.push_back(info); | |
| 283 } | |
| 284 | |
| 285 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 286 base::Bind(callback, clients)); | |
| 287 } | |
| 288 | |
| 289 } // namespace | 289 } // namespace |
| 290 | 290 |
| 291 ServiceWorkerVersion::ServiceWorkerVersion( | 291 ServiceWorkerVersion::ServiceWorkerVersion( |
| 292 ServiceWorkerRegistration* registration, | 292 ServiceWorkerRegistration* registration, |
| 293 const GURL& script_url, | 293 const GURL& script_url, |
| 294 int64 version_id, | 294 int64 version_id, |
| 295 base::WeakPtr<ServiceWorkerContextCore> context) | 295 base::WeakPtr<ServiceWorkerContextCore> context) |
| 296 : version_id_(version_id), | 296 : version_id_(version_id), |
| 297 registration_id_(kInvalidServiceWorkerVersionId), | 297 registration_id_(kInvalidServiceWorkerVersionId), |
| 298 script_url_(script_url), | 298 script_url_(script_url), |
| (...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 986 | 986 |
| 987 void ServiceWorkerVersion::OnGetClientDocuments(int request_id) { | 987 void ServiceWorkerVersion::OnGetClientDocuments(int request_id) { |
| 988 if (controllee_by_id_.IsEmpty()) { | 988 if (controllee_by_id_.IsEmpty()) { |
| 989 if (running_status() == RUNNING) { | 989 if (running_status() == RUNNING) { |
| 990 embedded_worker_->SendMessage( | 990 embedded_worker_->SendMessage( |
| 991 ServiceWorkerMsg_DidGetClientDocuments(request_id, | 991 ServiceWorkerMsg_DidGetClientDocuments(request_id, |
| 992 std::vector<ServiceWorkerClientInfo>())); | 992 std::vector<ServiceWorkerClientInfo>())); |
| 993 } | 993 } |
| 994 return; | 994 return; |
| 995 } | 995 } |
| 996 scoped_refptr<GetClientDocumentsCallback> callback( | 996 |
| 997 new GetClientDocumentsCallback(request_id, this)); | |
| 998 ControlleeByIDMap::iterator it(&controllee_by_id_); | |
| 999 TRACE_EVENT0("ServiceWorker", | 997 TRACE_EVENT0("ServiceWorker", |
| 1000 "ServiceWorkerVersion::OnGetClientDocuments"); | 998 "ServiceWorkerVersion::OnGetClientDocuments"); |
| 1001 while (!it.IsAtEnd()) { | 999 |
| 1002 // TODO(mlamouri): we could coalesce those requests into one. | 1000 std::vector<Tuple<int,int,int>> clients_info; |
| 1003 it.GetCurrentValue()->GetClientInfo( | 1001 for (ControlleeByIDMap::iterator it(&controllee_by_id_); !it.IsAtEnd(); |
| 1004 base::Bind(&ServiceWorkerVersion::DidGetClientInfo, | 1002 it.Advance()) { |
| 1005 weak_factory_.GetWeakPtr(), it.GetCurrentKey(), callback)); | 1003 int process_id = it.GetCurrentValue()->process_id(); |
| 1006 it.Advance(); | 1004 int frame_id = it.GetCurrentValue()->frame_id(); |
| 1005 int client_id = it.GetCurrentKey(); | |
| 1006 | |
| 1007 clients_info.push_back(MakeTuple(process_id, frame_id, client_id)); | |
| 1007 } | 1008 } |
| 1009 | |
| 1010 BrowserThread::PostTask( | |
| 1011 BrowserThread::UI, FROM_HERE, | |
| 1012 base::Bind(&OnGetClientDocumentsFromUI, clients_info, script_url_, | |
| 1013 base::Bind(&ServiceWorkerVersion::DidGetClientDocuments, | |
| 1014 weak_factory_.GetWeakPtr(), | |
| 1015 request_id))); | |
| 1016 | |
| 1008 } | 1017 } |
| 1009 | 1018 |
| 1010 void ServiceWorkerVersion::OnActivateEventFinished( | 1019 void ServiceWorkerVersion::OnActivateEventFinished( |
| 1011 int request_id, | 1020 int request_id, |
| 1012 blink::WebServiceWorkerEventResult result) { | 1021 blink::WebServiceWorkerEventResult result) { |
| 1013 DCHECK(ACTIVATING == status() || | 1022 DCHECK(ACTIVATING == status() || |
| 1014 REDUNDANT == status()) << status(); | 1023 REDUNDANT == status()) << status(); |
| 1015 TRACE_EVENT0("ServiceWorker", | 1024 TRACE_EVENT0("ServiceWorker", |
| 1016 "ServiceWorkerVersion::OnActivateEventFinished"); | 1025 "ServiceWorkerVersion::OnActivateEventFinished"); |
| 1017 | 1026 |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1390 if (status == SERVICE_WORKER_ERROR_ABORT) { | 1399 if (status == SERVICE_WORKER_ERROR_ABORT) { |
| 1391 embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError( | 1400 embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError( |
| 1392 request_id, blink::WebServiceWorkerError::ErrorTypeAbort, | 1401 request_id, blink::WebServiceWorkerError::ErrorTypeAbort, |
| 1393 base::ASCIIToUTF16(kClaimClientsShutdownErrorMesage))); | 1402 base::ASCIIToUTF16(kClaimClientsShutdownErrorMesage))); |
| 1394 return; | 1403 return; |
| 1395 } | 1404 } |
| 1396 DCHECK(status == SERVICE_WORKER_OK); | 1405 DCHECK(status == SERVICE_WORKER_OK); |
| 1397 embedded_worker_->SendMessage(ServiceWorkerMsg_DidClaimClients(request_id)); | 1406 embedded_worker_->SendMessage(ServiceWorkerMsg_DidClaimClients(request_id)); |
| 1398 } | 1407 } |
| 1399 | 1408 |
| 1400 void ServiceWorkerVersion::DidGetClientInfo( | 1409 void ServiceWorkerVersion::DidGetClientDocuments( |
| 1401 int client_id, | 1410 int request_id, |
| 1402 scoped_refptr<GetClientDocumentsCallback> callback, | 1411 const std::vector<ServiceWorkerClientInfo>& clients) { |
| 1403 const ServiceWorkerClientInfo& info) { | 1412 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1404 // If the request to the provider_host returned an empty | 1413 if (running_status() != RUNNING) |
| 1405 // ServiceWorkerClientInfo, that means that it wasn't possible to associate | |
| 1406 // it with a valid RenderFrameHost. It might be because the frame was killed | |
| 1407 // or navigated in between. | |
| 1408 if (info.IsEmpty()) | |
| 1409 return; | 1414 return; |
| 1410 | 1415 |
| 1411 // We can get info for a frame that was navigating end ended up with a | 1416 embedded_worker_->SendMessage( |
| 1412 // different URL than expected. In such case, we should make sure to not | 1417 ServiceWorkerMsg_DidGetClientDocuments(request_id, clients)); |
| 1413 // expose cross-origin WindowClient. | |
| 1414 if (info.url.GetOrigin() != script_url_.GetOrigin()) | |
| 1415 return; | |
| 1416 | |
| 1417 callback->AddClientInfo(client_id, info); | |
| 1418 } | 1418 } |
| 1419 | 1419 |
| 1420 void ServiceWorkerVersion::StartTimeoutTimer() { | 1420 void ServiceWorkerVersion::StartTimeoutTimer() { |
| 1421 DCHECK(!timeout_timer_.IsRunning()); | 1421 DCHECK(!timeout_timer_.IsRunning()); |
| 1422 ClearTick(&idle_time_); | 1422 ClearTick(&idle_time_); |
| 1423 ClearTick(&ping_time_); | 1423 ClearTick(&ping_time_); |
| 1424 ping_timed_out_ = false; | 1424 ping_timed_out_ = false; |
| 1425 timeout_timer_.Start(FROM_HERE, | 1425 timeout_timer_.Start(FROM_HERE, |
| 1426 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds), | 1426 base::TimeDelta::FromSeconds(kTimeoutTimerDelaySeconds), |
| 1427 this, &ServiceWorkerVersion::OnTimeoutTimer); | 1427 this, &ServiceWorkerVersion::OnTimeoutTimer); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1583 int request_id) { | 1583 int request_id) { |
| 1584 callbacks->Remove(request_id); | 1584 callbacks->Remove(request_id); |
| 1585 if (is_doomed_) { | 1585 if (is_doomed_) { |
| 1586 // The stop should be already scheduled, but try to stop immediately, in | 1586 // The stop should be already scheduled, but try to stop immediately, in |
| 1587 // order to release worker resources soon. | 1587 // order to release worker resources soon. |
| 1588 StopWorkerIfIdle(); | 1588 StopWorkerIfIdle(); |
| 1589 } | 1589 } |
| 1590 } | 1590 } |
| 1591 | 1591 |
| 1592 } // namespace content | 1592 } // namespace content |
| OLD | NEW |