| 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 |