| 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/stl_util.h" |    10 #include "base/stl_util.h" | 
|    10 #include "base/strings/string16.h" |    11 #include "base/strings/string16.h" | 
|    11 #include "base/strings/utf_string_conversions.h" |    12 #include "base/strings/utf_string_conversions.h" | 
|    12 #include "base/time/time.h" |    13 #include "base/time/time.h" | 
|    13 #include "content/browser/message_port_message_filter.h" |    14 #include "content/browser/message_port_message_filter.h" | 
|    14 #include "content/browser/message_port_service.h" |    15 #include "content/browser/message_port_service.h" | 
|    15 #include "content/browser/service_worker/embedded_worker_instance.h" |    16 #include "content/browser/service_worker/embedded_worker_instance.h" | 
|    16 #include "content/browser/service_worker/embedded_worker_registry.h" |    17 #include "content/browser/service_worker/embedded_worker_registry.h" | 
|    17 #include "content/browser/service_worker/service_worker_context_core.h" |    18 #include "content/browser/service_worker/service_worker_context_core.h" | 
|    18 #include "content/browser/service_worker/service_worker_context_wrapper.h" |    19 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|    29 #include "content/public/browser/web_contents_observer.h" |    30 #include "content/public/browser/web_contents_observer.h" | 
|    30 #include "content/public/common/child_process_host.h" |    31 #include "content/public/common/child_process_host.h" | 
|    31 #include "content/public/common/content_client.h" |    32 #include "content/public/common/content_client.h" | 
|    32 #include "content/public/common/content_switches.h" |    33 #include "content/public/common/content_switches.h" | 
|    33 #include "content/public/common/result_codes.h" |    34 #include "content/public/common/result_codes.h" | 
|    34 #include "net/http/http_response_info.h" |    35 #include "net/http/http_response_info.h" | 
|    35  |    36  | 
|    36 namespace content { |    37 namespace content { | 
|    37  |    38  | 
|    38 typedef ServiceWorkerVersion::StatusCallback StatusCallback; |    39 typedef ServiceWorkerVersion::StatusCallback StatusCallback; | 
|    39 typedef ServiceWorkerVersion::MessageCallback MessageCallback; |  | 
|    40  |    40  | 
|    41 class ServiceWorkerVersion::GetClientDocumentsCallback |    41 class ServiceWorkerVersion::GetClientDocumentsCallback | 
|    42     : public base::RefCounted<GetClientDocumentsCallback> { |    42     : public base::RefCounted<GetClientDocumentsCallback> { | 
|    43  public: |    43  public: | 
|    44   GetClientDocumentsCallback(int request_id, |    44   GetClientDocumentsCallback(int request_id, | 
|    45                              ServiceWorkerVersion* version) |    45                              ServiceWorkerVersion* version) | 
|    46       : request_id_(request_id), |    46       : request_id_(request_id), | 
|    47         version_(version) { |    47         version_(version) { | 
|    48     DCHECK(version_); |    48     DCHECK(version_); | 
|    49   } |    49   } | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    84  |    84  | 
|    85 // Default delay for scheduled update. |    85 // Default delay for scheduled update. | 
|    86 const int kUpdateDelaySeconds = 1; |    86 const int kUpdateDelaySeconds = 1; | 
|    87  |    87  | 
|    88 // Delay between sending pings to the worker. |    88 // Delay between sending pings to the worker. | 
|    89 const int kPingIntervalTime = 10;  // 10 secs. |    89 const int kPingIntervalTime = 10;  // 10 secs. | 
|    90  |    90  | 
|    91 // Timeout for waiting for a response to a ping. |    91 // Timeout for waiting for a response to a ping. | 
|    92 const int kPingTimeoutTime = 30;  // 30 secs. |    92 const int kPingTimeoutTime = 30;  // 30 secs. | 
|    93  |    93  | 
 |    94 // Timeout for the worker to start. | 
 |    95 const int kStartWorkerTimeoutMinutes = 5; | 
 |    96  | 
 |    97 // If the SW was destructed while starting up, how many seconds it | 
 |    98 // had to start up for this to be considered a timeout occurrence. | 
 |    99 const int kDestructedStartingWorkerTimeoutThresholdSeconds = 5;  // 5 secs. | 
 |   100  | 
|    94 const char kClaimClientsStateErrorMesage[] = |   101 const char kClaimClientsStateErrorMesage[] = | 
|    95     "Only the active worker can claim clients."; |   102     "Only the active worker can claim clients."; | 
|    96  |   103  | 
|    97 const char kClaimClientsShutdownErrorMesage[] = |   104 const char kClaimClientsShutdownErrorMesage[] = | 
|    98     "Failed to claim clients due to Service Worker system shutdown."; |   105     "Failed to claim clients due to Service Worker system shutdown."; | 
|    99  |   106  | 
|   100 void RunSoon(const base::Closure& callback) { |   107 void RunSoon(const base::Closure& callback) { | 
|   101   if (!callback.is_null()) |   108   if (!callback.is_null()) | 
|   102     base::MessageLoop::current()->PostTask(FROM_HERE, callback); |   109     base::MessageLoop::current()->PostTask(FROM_HERE, callback); | 
|   103 } |   110 } | 
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   300   if (registration) { |   307   if (registration) { | 
|   301     registration_id_ = registration->id(); |   308     registration_id_ = registration->id(); | 
|   302     scope_ = registration->pattern(); |   309     scope_ = registration->pattern(); | 
|   303   } |   310   } | 
|   304   context_->AddLiveVersion(this); |   311   context_->AddLiveVersion(this); | 
|   305   embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(); |   312   embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(); | 
|   306   embedded_worker_->AddListener(this); |   313   embedded_worker_->AddListener(this); | 
|   307 } |   314 } | 
|   308  |   315  | 
|   309 ServiceWorkerVersion::~ServiceWorkerVersion() { |   316 ServiceWorkerVersion::~ServiceWorkerVersion() { | 
 |   317   // The user may have closed the tab waiting for SW to start up. | 
 |   318   if (start_worker_timeout_timer_.IsRunning() && !start_timing_.is_null()) { | 
 |   319     if ((base::TimeTicks::Now() - start_timing_) > | 
 |   320         base::TimeDelta::FromSeconds( | 
 |   321             kDestructedStartingWorkerTimeoutThresholdSeconds)) { | 
 |   322       RecordStartWorkerResult(SERVICE_WORKER_ERROR_TIMEOUT); | 
 |   323     } | 
 |   324   } | 
 |   325  | 
|   310   embedded_worker_->RemoveListener(this); |   326   embedded_worker_->RemoveListener(this); | 
|   311   if (context_) |   327   if (context_) | 
|   312     context_->RemoveLiveVersion(version_id_); |   328     context_->RemoveLiveVersion(version_id_); | 
|   313   // EmbeddedWorker's dtor sends StopWorker if it's still running. |   329   // EmbeddedWorker's dtor sends StopWorker if it's still running. | 
|   314 } |   330 } | 
|   315  |   331  | 
|   316 void ServiceWorkerVersion::SetStatus(Status status) { |   332 void ServiceWorkerVersion::SetStatus(Status status) { | 
|   317   if (status_ == status) |   333   if (status_ == status) | 
|   318     return; |   334     return; | 
|   319  |   335  | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   361     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); |   377     RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); | 
|   362     return; |   378     return; | 
|   363   } |   379   } | 
|   364   switch (running_status()) { |   380   switch (running_status()) { | 
|   365     case RUNNING: |   381     case RUNNING: | 
|   366       RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |   382       RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 
|   367       return; |   383       return; | 
|   368     case STOPPING: |   384     case STOPPING: | 
|   369     case STOPPED: |   385     case STOPPED: | 
|   370     case STARTING: |   386     case STARTING: | 
 |   387       if (!start_worker_timeout_timer_.IsRunning()) | 
 |   388         ScheduleStartWorkerTimeout(); | 
|   371       start_callbacks_.push_back(callback); |   389       start_callbacks_.push_back(callback); | 
|   372       if (running_status() == STOPPED) { |   390       if (running_status() == STOPPED) { | 
|   373         DCHECK(!cache_listener_.get()); |   391         DCHECK(!cache_listener_.get()); | 
|   374         cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); |   392         cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); | 
|   375         embedded_worker_->Start( |   393         embedded_worker_->Start( | 
|   376             version_id_, |   394             version_id_, scope_, script_url_, pause_after_download, | 
|   377             scope_, |   395             base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated, | 
|   378             script_url_, |  | 
|   379             pause_after_download, |  | 
|   380             base::Bind(&ServiceWorkerVersion::OnStartMessageSent, |  | 
|   381                        weak_factory_.GetWeakPtr())); |   396                        weak_factory_.GetWeakPtr())); | 
|   382       } |   397       } | 
|   383       return; |   398       return; | 
|   384   } |   399   } | 
|   385 } |   400 } | 
|   386  |   401  | 
|   387 void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) { |   402 void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) { | 
|   388   if (running_status() == STOPPED) { |   403   if (running_status() == STOPPED) { | 
|   389     RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |   404     RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 
|   390     return; |   405     return; | 
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   761 void ServiceWorkerVersion::Doom() { |   776 void ServiceWorkerVersion::Doom() { | 
|   762   if (is_doomed_) |   777   if (is_doomed_) | 
|   763     return; |   778     return; | 
|   764   is_doomed_ = true; |   779   is_doomed_ = true; | 
|   765   if (!HasControllee()) |   780   if (!HasControllee()) | 
|   766     DoomInternal(); |   781     DoomInternal(); | 
|   767 } |   782 } | 
|   768  |   783  | 
|   769 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { |   784 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { | 
|   770   embedded_worker()->set_devtools_attached(attached); |   785   embedded_worker()->set_devtools_attached(attached); | 
|   771   if (attached) |   786   if (attached) { | 
 |   787     // Set to null time so we don't record the startup time metric. | 
 |   788     start_timing_ = base::TimeTicks(); | 
|   772     return; |   789     return; | 
 |   790   } | 
|   773   // If devtools is detached try scheduling the timers for stopping the worker |   791   // If devtools is detached try scheduling the timers for stopping the worker | 
|   774   // now. |   792   // now. | 
|   775   if (!stop_worker_timer_.IsRunning()) |   793   if (!stop_worker_timer_.IsRunning()) | 
|   776     ScheduleStopWorker(); |   794     ScheduleStopWorker(); | 
|   777   if (!ping_worker_timer_.IsRunning()) |   795   if (!ping_worker_timer_.IsRunning()) | 
|   778     StartPingWorker(); |   796     StartPingWorker(); | 
 |   797   if (!start_worker_timeout_timer_.IsRunning() && !start_callbacks_.empty()) | 
 |   798     ScheduleStartWorkerTimeout(); | 
|   779 } |   799 } | 
|   780  |   800  | 
|   781 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( |   801 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( | 
|   782     const net::HttpResponseInfo& http_info) { |   802     const net::HttpResponseInfo& http_info) { | 
|   783   main_script_http_info_.reset(new net::HttpResponseInfo(http_info)); |   803   main_script_http_info_.reset(new net::HttpResponseInfo(http_info)); | 
|   784 } |   804 } | 
|   785  |   805  | 
|   786 const net::HttpResponseInfo* |   806 const net::HttpResponseInfo* | 
|   787 ServiceWorkerVersion::GetMainScriptHttpResponseInfo() { |   807 ServiceWorkerVersion::GetMainScriptHttpResponseInfo() { | 
|   788   return main_script_http_info_.get(); |   808   return main_script_http_info_.get(); | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   852  |   872  | 
|   853   FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); |   873   FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); | 
|   854  |   874  | 
|   855   // There should be no more communication from/to a stopped worker. Deleting |   875   // There should be no more communication from/to a stopped worker. Deleting | 
|   856   // the listener prevents any pending completion callbacks from causing |   876   // the listener prevents any pending completion callbacks from causing | 
|   857   // messages to be sent to the stopped worker. |   877   // messages to be sent to the stopped worker. | 
|   858   cache_listener_.reset(); |   878   cache_listener_.reset(); | 
|   859  |   879  | 
|   860   // Restart worker if we have any start callbacks and the worker isn't doomed. |   880   // Restart worker if we have any start callbacks and the worker isn't doomed. | 
|   861   if (should_restart) { |   881   if (should_restart) { | 
 |   882     start_worker_timeout_timer_.Reset(); | 
|   862     cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); |   883     cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); | 
|   863     embedded_worker_->Start( |   884     embedded_worker_->Start( | 
|   864         version_id_, scope_, script_url_, false /* pause_after_download */, |   885         version_id_, scope_, script_url_, false /* pause_after_download */, | 
|   865         base::Bind(&ServiceWorkerVersion::OnStartMessageSent, |   886         base::Bind(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated, | 
|   866                    weak_factory_.GetWeakPtr())); |   887                    weak_factory_.GetWeakPtr())); | 
|   867   } |   888   } | 
|   868 } |   889 } | 
|   869  |   890  | 
|   870 void ServiceWorkerVersion::OnReportException( |   891 void ServiceWorkerVersion::OnReportException( | 
|   871     const base::string16& error_message, |   892     const base::string16& error_message, | 
|   872     int line_number, |   893     int line_number, | 
|   873     int column_number, |   894     int column_number, | 
|   874     const GURL& source_url) { |   895     const GURL& source_url) { | 
|   875   FOR_EACH_OBSERVER( |   896   FOR_EACH_OBSERVER( | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   928     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, |   949     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SkipWaiting, | 
|   929                         OnSkipWaiting) |   950                         OnSkipWaiting) | 
|   930     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients, |   951     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_ClaimClients, | 
|   931                         OnClaimClients) |   952                         OnClaimClients) | 
|   932     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_Pong, OnPongFromWorker) |   953     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_Pong, OnPongFromWorker) | 
|   933     IPC_MESSAGE_UNHANDLED(handled = false) |   954     IPC_MESSAGE_UNHANDLED(handled = false) | 
|   934   IPC_END_MESSAGE_MAP() |   955   IPC_END_MESSAGE_MAP() | 
|   935   return handled; |   956   return handled; | 
|   936 } |   957 } | 
|   937  |   958  | 
|   938 void ServiceWorkerVersion::OnStartMessageSent( |   959 void ServiceWorkerVersion::OnStartSentAndScriptEvaluated( | 
|   939     ServiceWorkerStatusCode status) { |   960     ServiceWorkerStatusCode status) { | 
|   940   if (status != SERVICE_WORKER_OK) |   961   if (status != SERVICE_WORKER_OK) | 
|   941     RunCallbacks(this, &start_callbacks_, status); |   962     RunCallbacks(this, &start_callbacks_, status); | 
|   942 } |   963 } | 
|   943  |   964  | 
|   944 void ServiceWorkerVersion::DispatchInstallEventAfterStartWorker( |   965 void ServiceWorkerVersion::DispatchInstallEventAfterStartWorker( | 
|   945     const StatusCallback& callback) { |   966     const StatusCallback& callback) { | 
|   946   DCHECK_EQ(RUNNING, running_status()) |   967   DCHECK_EQ(RUNNING, running_status()) | 
|   947       << "Worker stopped too soon after it was started."; |   968       << "Worker stopped too soon after it was started."; | 
|   948  |   969  | 
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1429                            base::TimeDelta::FromSeconds(kPingIntervalTime), |  1450                            base::TimeDelta::FromSeconds(kPingIntervalTime), | 
|  1430                            base::Bind(&ServiceWorkerVersion::PingWorker, |  1451                            base::Bind(&ServiceWorkerVersion::PingWorker, | 
|  1431                                       weak_factory_.GetWeakPtr())); |  1452                                       weak_factory_.GetWeakPtr())); | 
|  1432 } |  1453 } | 
|  1433  |  1454  | 
|  1434 void ServiceWorkerVersion::OnPingTimeout() { |  1455 void ServiceWorkerVersion::OnPingTimeout() { | 
|  1435   if (running_status() != STARTING && running_status() != RUNNING) |  1456   if (running_status() != STARTING && running_status() != RUNNING) | 
|  1436     return; |  1457     return; | 
|  1437   ping_timed_out_ = true; |  1458   ping_timed_out_ = true; | 
|  1438   // TODO(falken): Show a message to the developer that the SW was stopped due |  1459   // TODO(falken): Show a message to the developer that the SW was stopped due | 
|  1439   // to timeout (crbug.com/457968). |  1460   // to timeout (crbug.com/457968). Also, change the error code to | 
 |  1461   // SERVICE_WORKER_ERROR_TIMEOUT. | 
|  1440   StopWorkerIfIdle(); |  1462   StopWorkerIfIdle(); | 
|  1441 } |  1463 } | 
|  1442  |  1464  | 
|  1443 void ServiceWorkerVersion::ScheduleStopWorker() { |  1465 void ServiceWorkerVersion::ScheduleStopWorker() { | 
|  1444   if (running_status() != RUNNING) |  1466   if (running_status() != RUNNING) | 
|  1445     return; |  1467     return; | 
|  1446   stop_worker_timer_.Stop(); |  1468   stop_worker_timer_.Stop(); | 
|  1447   stop_worker_timer_.Start( |  1469   stop_worker_timer_.Start( | 
|  1448       FROM_HERE, base::TimeDelta::FromSeconds( |  1470       FROM_HERE, base::TimeDelta::FromSeconds( | 
|  1449           is_doomed_ ? kStopDoomedWorkerDelay : kStopWorkerDelay), |  1471           is_doomed_ ? kStopDoomedWorkerDelay : kStopWorkerDelay), | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|  1473     !install_callbacks_.IsEmpty() || |  1495     !install_callbacks_.IsEmpty() || | 
|  1474     !fetch_callbacks_.IsEmpty() || |  1496     !fetch_callbacks_.IsEmpty() || | 
|  1475     !sync_callbacks_.IsEmpty() || |  1497     !sync_callbacks_.IsEmpty() || | 
|  1476     !notification_click_callbacks_.IsEmpty() || |  1498     !notification_click_callbacks_.IsEmpty() || | 
|  1477     !push_callbacks_.IsEmpty() || |  1499     !push_callbacks_.IsEmpty() || | 
|  1478     !geofencing_callbacks_.IsEmpty() || |  1500     !geofencing_callbacks_.IsEmpty() || | 
|  1479     !cross_origin_connect_callbacks_.IsEmpty() || |  1501     !cross_origin_connect_callbacks_.IsEmpty() || | 
|  1480     !streaming_url_request_jobs_.empty(); |  1502     !streaming_url_request_jobs_.empty(); | 
|  1481 } |  1503 } | 
|  1482  |  1504  | 
 |  1505 void ServiceWorkerVersion::ScheduleStartWorkerTimeout() { | 
 |  1506   DCHECK(!start_worker_timeout_timer_.IsRunning()); | 
 |  1507   start_timing_ = embedded_worker_->devtools_attached() | 
 |  1508                       ? base::TimeTicks() | 
 |  1509                       : base::TimeTicks::Now(); | 
 |  1510   start_callbacks_.push_back( | 
 |  1511       base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, | 
 |  1512                  weak_factory_.GetWeakPtr())); | 
 |  1513   start_worker_timeout_timer_.Start( | 
 |  1514       FROM_HERE, base::TimeDelta::FromMinutes(kStartWorkerTimeoutMinutes), | 
 |  1515       base::Bind(&ServiceWorkerVersion::OnStartWorkerTimeout, | 
 |  1516                  weak_factory_.GetWeakPtr())); | 
 |  1517 } | 
 |  1518  | 
 |  1519 void ServiceWorkerVersion::OnStartWorkerTimeout() { | 
 |  1520   DCHECK(running_status() == STARTING || running_status() == STOPPING) | 
 |  1521       << running_status(); | 
 |  1522  | 
 |  1523   if (embedded_worker_->devtools_attached()) { | 
 |  1524     start_worker_timeout_timer_.Stop(); | 
 |  1525     return; | 
 |  1526   } | 
 |  1527  | 
 |  1528   scoped_refptr<ServiceWorkerVersion> protect(this); | 
 |  1529   RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); | 
 |  1530   if (running_status() == STARTING) | 
 |  1531     embedded_worker_->Stop(); | 
 |  1532 } | 
 |  1533  | 
 |  1534 void ServiceWorkerVersion::RecordStartWorkerResult( | 
 |  1535     ServiceWorkerStatusCode status) { | 
 |  1536   start_worker_timeout_timer_.Stop(); | 
 |  1537  | 
 |  1538   UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Status", status, | 
 |  1539                             SERVICE_WORKER_ERROR_MAX_VALUE); | 
 |  1540   if (status == SERVICE_WORKER_OK && !start_timing_.is_null()) { | 
 |  1541     UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.StartWorker.Time", | 
 |  1542                                base::TimeTicks::Now() - start_timing_); | 
 |  1543   } | 
 |  1544  | 
 |  1545   if (status != SERVICE_WORKER_ERROR_TIMEOUT) | 
 |  1546     return; | 
 |  1547   EmbeddedWorkerInstance::StartingPhase phase = | 
 |  1548       EmbeddedWorkerInstance::NOT_STARTING; | 
 |  1549   EmbeddedWorkerInstance::Status running_status = embedded_worker_->status(); | 
 |  1550   // Build an artifical JavaScript exception to show in the ServiceWorker | 
 |  1551   // log for developers; it's not user-facing so it's not a localized resource. | 
 |  1552   std::string message = "ServiceWorker startup timed out. "; | 
 |  1553   if (running_status != EmbeddedWorkerInstance::STARTING) { | 
 |  1554     message.append("The worker had unexpected status: "); | 
 |  1555     message.append(EmbeddedWorkerInstance::StatusToString(running_status)); | 
 |  1556   } else { | 
 |  1557     phase = embedded_worker_->starting_phase(); | 
 |  1558     message.append("The worker was in startup phase: "); | 
 |  1559     message.append(EmbeddedWorkerInstance::StartingPhaseToString(phase)); | 
 |  1560   } | 
 |  1561   message.append("."); | 
 |  1562   OnReportException(base::UTF8ToUTF16(message), -1, -1, GURL()); | 
 |  1563   DVLOG(1) << message; | 
 |  1564   UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.TimeoutPhase", | 
 |  1565                             phase, | 
 |  1566                             EmbeddedWorkerInstance::STARTING_PHASE_MAX_VALUE); | 
 |  1567 } | 
 |  1568  | 
|  1483 void ServiceWorkerVersion::DoomInternal() { |  1569 void ServiceWorkerVersion::DoomInternal() { | 
|  1484   DCHECK(is_doomed_); |  1570   DCHECK(is_doomed_); | 
|  1485   DCHECK(!HasControllee()); |  1571   DCHECK(!HasControllee()); | 
|  1486   SetStatus(REDUNDANT); |  1572   SetStatus(REDUNDANT); | 
|  1487   StopWorkerIfIdle(); |  1573   StopWorkerIfIdle(); | 
|  1488   if (!context_) |  1574   if (!context_) | 
|  1489     return; |  1575     return; | 
|  1490   std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |  1576   std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 
|  1491   script_cache_map_.GetResources(&resources); |  1577   script_cache_map_.GetResources(&resources); | 
|  1492   context_->storage()->PurgeResources(resources); |  1578   context_->storage()->PurgeResources(resources); | 
|  1493 } |  1579 } | 
|  1494  |  1580  | 
|  1495 template <typename IDMAP> |  1581 template <typename IDMAP> | 
|  1496 void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed( |  1582 void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed( | 
|  1497     IDMAP* callbacks, |  1583     IDMAP* callbacks, | 
|  1498     int request_id) { |  1584     int request_id) { | 
|  1499   callbacks->Remove(request_id); |  1585   callbacks->Remove(request_id); | 
|  1500   if (is_doomed_) { |  1586   if (is_doomed_) { | 
|  1501     // The stop should be already scheduled, but try to stop immediately, in |  1587     // The stop should be already scheduled, but try to stop immediately, in | 
|  1502     // order to release worker resources soon. |  1588     // order to release worker resources soon. | 
|  1503     StopWorkerIfIdle(); |  1589     StopWorkerIfIdle(); | 
|  1504   } |  1590   } | 
|  1505 } |  1591 } | 
|  1506  |  1592  | 
|  1507 }  // namespace content |  1593 }  // namespace content | 
| OLD | NEW |