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..a6ce9a63af2c35a8f0c4e6a3bd92d350017a79a8 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,12 @@ 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_[EventType::FETCH_MAIN_FRAME].fired_events != 0 || |
+ event_stats_[EventType::FETCH_SUB_FRAME].fired_events != 0); |
+ } |
} |
void RecordEventHandledStatus(EventType event, bool handled) { |
@@ -225,6 +232,7 @@ class ServiceWorkerVersion::Metrics { |
ServiceWorkerVersion* owner_; |
std::map<EventType, EventStat> event_stats_; |
+ const EventType start_worker_purpose_; |
DISALLOW_COPY_AND_ASSIGN(Metrics); |
}; |
@@ -778,7 +786,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 +895,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 +1335,8 @@ 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_ = purpose; |
start_callbacks_.push_back( |
base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, |
weak_factory_.GetWeakPtr(), purpose, prestart_status, |
@@ -1349,7 +1358,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_.value())); |
+ |
+ // 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 +1478,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 +1710,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 +1756,9 @@ void ServiceWorkerVersion::OnBeginEvent() { |
idle_time_); |
} |
+void ServiceWorkerVersion::FinishStartWorker(ServiceWorkerStatusCode status) { |
+ start_worker_first_purpose_ = base::nullopt; |
+ RunCallbacks(this, &start_callbacks_, status); |
+} |
+ |
} // namespace content |