 Chromium Code Reviews
 Chromium Code Reviews Issue 2045153003:
  Speculatively launch Service Workers on mouse/touch events. [4/5]  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 2045153003:
  Speculatively launch Service Workers on mouse/touch events. [4/5]  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: content/browser/service_worker/service_worker_version.cc | 
| diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc | 
| index c9f14e5bbe052ee152eb13e47d1bef2323680fe7..4a833b8169ee7bea9f827800e62622acd27f297a 100644 | 
| --- a/content/browser/service_worker/service_worker_version.cc | 
| +++ b/content/browser/service_worker/service_worker_version.cc | 
| @@ -201,7 +201,8 @@ const int ServiceWorkerVersion::kStopWorkerTimeoutSeconds = 5; | 
| class ServiceWorkerVersion::Metrics { | 
| public: | 
| using EventType = ServiceWorkerMetrics::EventType; | 
| - explicit Metrics(ServiceWorkerVersion* owner) : owner_(owner) {} | 
| + explicit Metrics(ServiceWorkerVersion* owner, EventType start_worker_purpose) | 
| + : owner_(owner), start_worker_purpose_(start_worker_purpose) {} | 
| ~Metrics() { | 
| if (owner_->should_exclude_from_uma_) | 
| return; | 
| @@ -209,6 +210,10 @@ class ServiceWorkerVersion::Metrics { | 
| ServiceWorkerMetrics::RecordEventHandledRatio( | 
| ev.first, ev.second.handled_events, ev.second.fired_events); | 
| } | 
| + if (ServiceWorkerMetrics::IsNavigationHintEvent(start_worker_purpose_)) { | 
| + ServiceWorkerMetrics::RecordNavigationHintPrecision( | 
| + start_worker_purpose_, !event_stats_.empty()); | 
| 
nhiroki
2016/07/28 05:38:37
Regarding |event_fired|, we might want to filter o
 
horo
2016/07/28 08:15:48
Done.
 | 
| + } | 
| } | 
| void RecordEventHandledStatus(EventType event, bool handled) { | 
| @@ -225,6 +230,7 @@ class ServiceWorkerVersion::Metrics { | 
| ServiceWorkerVersion* owner_; | 
| std::map<EventType, EventStat> event_stats_; | 
| + const EventType start_worker_purpose_; | 
| DISALLOW_COPY_AND_ASSIGN(Metrics); | 
| }; | 
| @@ -778,7 +784,7 @@ void ServiceWorkerVersion::OnStarted() { | 
| // Fire all start callbacks. | 
| scoped_refptr<ServiceWorkerVersion> protect(this); | 
| - RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); | 
| + FinishStartWorker(SERVICE_WORKER_OK); | 
| FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); | 
| } | 
| @@ -887,8 +893,7 @@ void ServiceWorkerVersion::OnStartSentAndScriptEvaluated( | 
| ServiceWorkerStatusCode status) { | 
| if (status != SERVICE_WORKER_OK) { | 
| scoped_refptr<ServiceWorkerVersion> protect(this); | 
| - RunCallbacks(this, &start_callbacks_, | 
| - DeduceStartWorkerFailureReason(status)); | 
| + FinishStartWorker(DeduceStartWorkerFailureReason(status)); | 
| } | 
| } | 
| @@ -1328,6 +1333,9 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker( | 
| "ServiceWorker", "ServiceWorkerVersion::StartWorker", trace_id, | 
| "Script", script_url_.spec(), "Purpose", | 
| ServiceWorkerMetrics::EventTypeToString(purpose)); | 
| + DCHECK(!start_worker_first_purpose_); | 
| + start_worker_first_purpose_.reset( | 
| + new ServiceWorkerMetrics::EventType(purpose)); | 
| start_callbacks_.push_back( | 
| base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, | 
| weak_factory_.GetWeakPtr(), purpose, prestart_status, | 
| @@ -1349,7 +1357,12 @@ void ServiceWorkerVersion::StartWorkerInternal() { | 
| DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status()); | 
| DCHECK(!metrics_); | 
| - metrics_.reset(new Metrics(this)); | 
| + DCHECK(start_worker_first_purpose_); | 
| + metrics_.reset(new Metrics(this, *start_worker_first_purpose_)); | 
| + | 
| + // We don't clear |start_worker_first_purpose_| here but clear in | 
| + // FinishStartWorker. This is because StartWorkerInternal may be called | 
| + // again from OnStoppedInternal if StopWorker is called before OnStarted. | 
| StartTimeoutTimer(); | 
| @@ -1464,7 +1477,7 @@ void ServiceWorkerVersion::OnTimeoutTimer() { | 
| running_status() == EmbeddedWorkerStatus::STOPPING) | 
| << static_cast<int>(running_status()); | 
| scoped_refptr<ServiceWorkerVersion> protect(this); | 
| - RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); | 
| + FinishStartWorker(SERVICE_WORKER_ERROR_TIMEOUT); | 
| if (running_status() == EmbeddedWorkerStatus::STARTING) | 
| embedded_worker_->Stop(); | 
| return; | 
| @@ -1696,9 +1709,8 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) { | 
| if (!should_restart) { | 
| // Let all start callbacks fail. | 
| - RunCallbacks(this, &start_callbacks_, | 
| - DeduceStartWorkerFailureReason( | 
| - SERVICE_WORKER_ERROR_START_WORKER_FAILED)); | 
| + FinishStartWorker(DeduceStartWorkerFailureReason( | 
| + SERVICE_WORKER_ERROR_START_WORKER_FAILED)); | 
| } | 
| // Let all message callbacks fail (this will also fire and clear all | 
| @@ -1743,4 +1755,9 @@ void ServiceWorkerVersion::OnBeginEvent() { | 
| idle_time_); | 
| } | 
| +void ServiceWorkerVersion::FinishStartWorker(ServiceWorkerStatusCode status) { | 
| + start_worker_first_purpose_.reset(); | 
| + RunCallbacks(this, &start_callbacks_, status); | 
| +} | 
| + | 
| } // namespace content |