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