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