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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 false, // is_focused | 341 false, // is_focused |
342 host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, host_client_type); | 342 host->document_url(), REQUEST_CONTEXT_FRAME_TYPE_NONE, host_client_type); |
343 client_info.client_uuid = host->client_uuid(); | 343 client_info.client_uuid = host->client_uuid(); |
344 clients->push_back(client_info); | 344 clients->push_back(client_info); |
345 } | 345 } |
346 | 346 |
347 bool IsInstalled(ServiceWorkerVersion::Status status) { | 347 bool IsInstalled(ServiceWorkerVersion::Status status) { |
348 switch (status) { | 348 switch (status) { |
349 case ServiceWorkerVersion::NEW: | 349 case ServiceWorkerVersion::NEW: |
350 case ServiceWorkerVersion::INSTALLING: | 350 case ServiceWorkerVersion::INSTALLING: |
351 case ServiceWorkerVersion::REDUNDANT: | |
352 return false; | 351 return false; |
353 case ServiceWorkerVersion::INSTALLED: | 352 case ServiceWorkerVersion::INSTALLED: |
354 case ServiceWorkerVersion::ACTIVATING: | 353 case ServiceWorkerVersion::ACTIVATING: |
355 case ServiceWorkerVersion::ACTIVATED: | 354 case ServiceWorkerVersion::ACTIVATED: |
356 return true; | 355 return true; |
| 356 case ServiceWorkerVersion::REDUNDANT: |
| 357 NOTREACHED() << "Cannot use REDUNDANT here."; |
| 358 return false; |
357 } | 359 } |
358 NOTREACHED() << "Unexpected status: " << status; | 360 NOTREACHED() << "Unexpected status: " << status; |
359 return false; | 361 return false; |
360 } | 362 } |
361 | 363 |
362 } // namespace | 364 } // namespace |
363 | 365 |
364 const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5; | 366 const int ServiceWorkerVersion::kStartWorkerTimeoutMinutes = 5; |
365 const int ServiceWorkerVersion::kRequestTimeoutMinutes = 5; | 367 const int ServiceWorkerVersion::kRequestTimeoutMinutes = 5; |
366 | 368 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 StartWorker(false, callback); | 447 StartWorker(false, callback); |
446 } | 448 } |
447 | 449 |
448 void ServiceWorkerVersion::StartWorker( | 450 void ServiceWorkerVersion::StartWorker( |
449 bool pause_after_download, | 451 bool pause_after_download, |
450 const StatusCallback& callback) { | 452 const StatusCallback& callback) { |
451 if (!context_) { | 453 if (!context_) { |
452 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT)); | 454 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_ABORT)); |
453 return; | 455 return; |
454 } | 456 } |
| 457 if (status_ == REDUNDANT) { |
| 458 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); |
| 459 return; |
| 460 } |
| 461 prestart_status_ = status_; |
455 | 462 |
456 // Ensure the live registration during starting worker so that the worker can | 463 // Ensure the live registration during starting worker so that the worker can |
457 // get associated with it in SWDispatcherHost::OnSetHostedVersionId(). | 464 // get associated with it in SWDispatcherHost::OnSetHostedVersionId(). |
458 context_->storage()->FindRegistrationForId( | 465 context_->storage()->FindRegistrationForId( |
459 registration_id_, | 466 registration_id_, |
460 scope_.GetOrigin(), | 467 scope_.GetOrigin(), |
461 base::Bind(&ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker, | 468 base::Bind(&ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker, |
462 weak_factory_.GetWeakPtr(), | 469 weak_factory_.GetWeakPtr(), |
463 pause_after_download, | 470 pause_after_download, |
464 callback)); | 471 callback)); |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 void ServiceWorkerVersion::ReportError(ServiceWorkerStatusCode status, | 837 void ServiceWorkerVersion::ReportError(ServiceWorkerStatusCode status, |
831 const std::string& status_message) { | 838 const std::string& status_message) { |
832 if (status_message.empty()) { | 839 if (status_message.empty()) { |
833 OnReportException(base::UTF8ToUTF16(ServiceWorkerStatusToString(status)), | 840 OnReportException(base::UTF8ToUTF16(ServiceWorkerStatusToString(status)), |
834 -1, -1, GURL()); | 841 -1, -1, GURL()); |
835 } else { | 842 } else { |
836 OnReportException(base::UTF8ToUTF16(status_message), -1, -1, GURL()); | 843 OnReportException(base::UTF8ToUTF16(status_message), -1, -1, GURL()); |
837 } | 844 } |
838 } | 845 } |
839 | 846 |
| 847 void ServiceWorkerVersion::SetStartWorkerStatusCode( |
| 848 ServiceWorkerStatusCode status) { |
| 849 start_worker_status_ = status; |
| 850 } |
| 851 |
840 void ServiceWorkerVersion::Doom() { | 852 void ServiceWorkerVersion::Doom() { |
841 DCHECK(!HasControllee()); | 853 DCHECK(!HasControllee()); |
842 SetStatus(REDUNDANT); | 854 SetStatus(REDUNDANT); |
843 StopWorkerIfIdle(); | 855 StopWorkerIfIdle(); |
844 if (!context_) | 856 if (!context_) |
845 return; | 857 return; |
846 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 858 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
847 script_cache_map_.GetResources(&resources); | 859 script_cache_map_.GetResources(&resources); |
848 context_->storage()->PurgeResources(resources); | 860 context_->storage()->PurgeResources(resources); |
849 } | 861 } |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1507 | 1519 |
1508 void ServiceWorkerVersion::OnPongFromWorker() { | 1520 void ServiceWorkerVersion::OnPongFromWorker() { |
1509 ClearTick(&ping_time_); | 1521 ClearTick(&ping_time_); |
1510 } | 1522 } |
1511 | 1523 |
1512 void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker( | 1524 void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker( |
1513 bool pause_after_download, | 1525 bool pause_after_download, |
1514 const StatusCallback& callback, | 1526 const StatusCallback& callback, |
1515 ServiceWorkerStatusCode status, | 1527 ServiceWorkerStatusCode status, |
1516 const scoped_refptr<ServiceWorkerRegistration>& protect) { | 1528 const scoped_refptr<ServiceWorkerRegistration>& protect) { |
1517 if (status != SERVICE_WORKER_OK || is_redundant()) { | 1529 if (status != SERVICE_WORKER_OK) { |
1518 RecordStartWorkerResult(status); | 1530 RecordStartWorkerResult(status); |
1519 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); | 1531 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); |
1520 return; | 1532 return; |
1521 } | 1533 } |
| 1534 if (is_redundant()) { |
| 1535 RecordStartWorkerResult(SERVICE_WORKER_ERROR_NOT_FOUND); |
| 1536 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); |
| 1537 return; |
| 1538 } |
1522 | 1539 |
1523 switch (running_status()) { | 1540 switch (running_status()) { |
1524 case RUNNING: | 1541 case RUNNING: |
1525 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 1542 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
1526 return; | 1543 return; |
1527 case STOPPING: | 1544 case STOPPING: |
1528 case STOPPED: | 1545 case STOPPED: |
1529 case STARTING: | 1546 case STARTING: |
1530 if (start_callbacks_.empty()) { | 1547 if (start_callbacks_.empty()) { |
1531 start_callbacks_.push_back( | 1548 start_callbacks_.push_back( |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1735 !geofencing_callbacks_.IsEmpty() || | 1752 !geofencing_callbacks_.IsEmpty() || |
1736 !cross_origin_connect_callbacks_.IsEmpty() || | 1753 !cross_origin_connect_callbacks_.IsEmpty() || |
1737 !streaming_url_request_jobs_.empty(); | 1754 !streaming_url_request_jobs_.empty(); |
1738 } | 1755 } |
1739 | 1756 |
1740 void ServiceWorkerVersion::RecordStartWorkerResult( | 1757 void ServiceWorkerVersion::RecordStartWorkerResult( |
1741 ServiceWorkerStatusCode status) { | 1758 ServiceWorkerStatusCode status) { |
1742 base::TimeTicks start_time = start_time_; | 1759 base::TimeTicks start_time = start_time_; |
1743 ClearTick(&start_time_); | 1760 ClearTick(&start_time_); |
1744 | 1761 |
1745 // Failing to start a redundant worker isn't interesting and very common when | 1762 ServiceWorkerMetrics::RecordStartWorkerStatus(status, |
1746 // update dooms because the script is byte-to-byte identical. | 1763 IsInstalled(prestart_status_)); |
1747 if (is_redundant()) | |
1748 return; | |
1749 | |
1750 ServiceWorkerMetrics::RecordStartWorkerStatus(status, IsInstalled(status_)); | |
1751 | 1764 |
1752 if (status == SERVICE_WORKER_OK && !start_time.is_null() && | 1765 if (status == SERVICE_WORKER_OK && !start_time.is_null() && |
1753 !skip_recording_startup_time_) { | 1766 !skip_recording_startup_time_) { |
1754 ServiceWorkerMetrics::RecordStartWorkerTime(GetTickDuration(start_time), | 1767 ServiceWorkerMetrics::RecordStartWorkerTime(GetTickDuration(start_time), |
1755 IsInstalled(status_)); | 1768 IsInstalled(prestart_status_)); |
1756 } | 1769 } |
1757 | 1770 |
1758 if (status != SERVICE_WORKER_ERROR_TIMEOUT) | 1771 if (status != SERVICE_WORKER_ERROR_TIMEOUT) |
1759 return; | 1772 return; |
1760 EmbeddedWorkerInstance::StartingPhase phase = | 1773 EmbeddedWorkerInstance::StartingPhase phase = |
1761 EmbeddedWorkerInstance::NOT_STARTING; | 1774 EmbeddedWorkerInstance::NOT_STARTING; |
1762 EmbeddedWorkerInstance::Status running_status = embedded_worker_->status(); | 1775 EmbeddedWorkerInstance::Status running_status = embedded_worker_->status(); |
1763 // Build an artifical JavaScript exception to show in the ServiceWorker | 1776 // Build an artifical JavaScript exception to show in the ServiceWorker |
1764 // log for developers; it's not user-facing so it's not a localized resource. | 1777 // log for developers; it's not user-facing so it's not a localized resource. |
1765 std::string message = "ServiceWorker startup timed out. "; | 1778 std::string message = "ServiceWorker startup timed out. "; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1844 requests_.pop(); | 1857 requests_.pop(); |
1845 } | 1858 } |
1846 requests_ = new_requests; | 1859 requests_ = new_requests; |
1847 } | 1860 } |
1848 | 1861 |
1849 ServiceWorkerStatusCode ServiceWorkerVersion::DeduceStartWorkerFailureReason( | 1862 ServiceWorkerStatusCode ServiceWorkerVersion::DeduceStartWorkerFailureReason( |
1850 ServiceWorkerStatusCode default_code) { | 1863 ServiceWorkerStatusCode default_code) { |
1851 if (ping_state_ == PING_TIMED_OUT) | 1864 if (ping_state_ == PING_TIMED_OUT) |
1852 return SERVICE_WORKER_ERROR_TIMEOUT; | 1865 return SERVICE_WORKER_ERROR_TIMEOUT; |
1853 | 1866 |
| 1867 if (start_worker_status_ != SERVICE_WORKER_OK) |
| 1868 return start_worker_status_; |
| 1869 |
1854 const net::URLRequestStatus& main_script_status = | 1870 const net::URLRequestStatus& main_script_status = |
1855 script_cache_map()->main_script_status(); | 1871 script_cache_map()->main_script_status(); |
1856 if (main_script_status.status() != net::URLRequestStatus::SUCCESS) { | 1872 if (main_script_status.status() != net::URLRequestStatus::SUCCESS) { |
1857 switch (main_script_status.error()) { | 1873 switch (main_script_status.error()) { |
1858 case net::ERR_INSECURE_RESPONSE: | 1874 case net::ERR_INSECURE_RESPONSE: |
1859 case net::ERR_UNSAFE_REDIRECT: | 1875 case net::ERR_UNSAFE_REDIRECT: |
1860 return SERVICE_WORKER_ERROR_SECURITY; | 1876 return SERVICE_WORKER_ERROR_SECURITY; |
1861 case net::ERR_ABORTED: | 1877 case net::ERR_ABORTED: |
1862 return SERVICE_WORKER_ERROR_ABORT; | 1878 return SERVICE_WORKER_ERROR_ABORT; |
1863 default: | 1879 default: |
1864 return SERVICE_WORKER_ERROR_NETWORK; | 1880 return SERVICE_WORKER_ERROR_NETWORK; |
1865 } | 1881 } |
1866 } | 1882 } |
1867 | 1883 |
1868 return default_code; | 1884 return default_code; |
1869 } | 1885 } |
1870 | 1886 |
1871 } // namespace content | 1887 } // namespace content |
OLD | NEW |