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