Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_fetch_dispatcher.h" | 5 #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" |
| 6 | 6 |
| 7 #include <string> | |
| 7 #include <utility> | 8 #include <utility> |
| 8 | 9 |
| 9 #include "base/bind.h" | 10 #include "base/bind.h" |
| 10 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 11 #include "content/browser/service_worker/embedded_worker_status.h" | 12 #include "content/browser/service_worker/embedded_worker_status.h" |
| 12 #include "content/browser/service_worker/service_worker_version.h" | 13 #include "content/browser/service_worker/service_worker_version.h" |
| 13 #include "content/common/service_worker/service_worker_messages.h" | 14 #include "content/common/service_worker/service_worker_messages.h" |
| 14 | 15 |
| 15 namespace content { | 16 namespace content { |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 19 | |
| 18 using EventType = ServiceWorkerMetrics::EventType; | 20 using EventType = ServiceWorkerMetrics::EventType; |
| 19 EventType ResourceTypeToEventType(ResourceType resource_type) { | 21 EventType ResourceTypeToEventType(ResourceType resource_type) { |
| 20 switch (resource_type) { | 22 switch (resource_type) { |
| 21 case RESOURCE_TYPE_MAIN_FRAME: | 23 case RESOURCE_TYPE_MAIN_FRAME: |
| 22 return EventType::FETCH_MAIN_FRAME; | 24 return EventType::FETCH_MAIN_FRAME; |
| 23 case RESOURCE_TYPE_SUB_FRAME: | 25 case RESOURCE_TYPE_SUB_FRAME: |
| 24 return EventType::FETCH_SUB_FRAME; | 26 return EventType::FETCH_SUB_FRAME; |
| 25 case RESOURCE_TYPE_SHARED_WORKER: | 27 case RESOURCE_TYPE_SHARED_WORKER: |
| 26 return EventType::FETCH_SHARED_WORKER; | 28 return EventType::FETCH_SHARED_WORKER; |
| 27 case RESOURCE_TYPE_SERVICE_WORKER: | 29 case RESOURCE_TYPE_SERVICE_WORKER: |
| 28 case RESOURCE_TYPE_LAST_TYPE: | 30 case RESOURCE_TYPE_LAST_TYPE: |
| 29 NOTREACHED() << resource_type; | 31 NOTREACHED() << resource_type; |
| 30 return EventType::FETCH_SUB_RESOURCE; | 32 return EventType::FETCH_SUB_RESOURCE; |
| 31 default: | 33 default: |
| 32 return EventType::FETCH_SUB_RESOURCE; | 34 return EventType::FETCH_SUB_RESOURCE; |
| 33 } | 35 } |
| 34 } | 36 } |
| 37 | |
| 38 std::unique_ptr<base::Value> NetLogServiceWorkerStatusCallback( | |
| 39 ServiceWorkerStatusCode status, | |
| 40 net::NetLogCaptureMode) { | |
| 41 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); | |
| 42 dict->SetString("status", ServiceWorkerStatusToString(status)); | |
| 43 return std::move(dict); | |
| 44 } | |
| 45 | |
| 46 std::unique_ptr<base::Value> NetLogFetchEventCallback( | |
| 47 ServiceWorkerStatusCode status, | |
| 48 ServiceWorkerFetchEventResult result, | |
| 49 net::NetLogCaptureMode) { | |
| 50 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); | |
| 51 dict->SetString("status", ServiceWorkerStatusToString(status)); | |
| 52 dict->SetBoolean("has_response", | |
| 53 result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE); | |
| 54 return std::move(dict); | |
| 55 } | |
| 56 | |
| 57 void EndNetLogEventWithServiceWorkerStatus(const net::BoundNetLog& net_log, | |
| 58 net::NetLog::EventType type, | |
| 59 ServiceWorkerStatusCode status) { | |
| 60 net_log.EndEvent(type, | |
| 61 base::Bind(&NetLogServiceWorkerStatusCallback, status)); | |
| 62 } | |
| 63 | |
| 35 } // namespace | 64 } // namespace |
| 36 | 65 |
| 37 ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher( | 66 ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher( |
| 38 std::unique_ptr<ServiceWorkerFetchRequest> request, | 67 std::unique_ptr<ServiceWorkerFetchRequest> request, |
| 39 ServiceWorkerVersion* version, | 68 ServiceWorkerVersion* version, |
| 40 ResourceType resource_type, | 69 ResourceType resource_type, |
| 70 const net::BoundNetLog& net_log, | |
| 41 const base::Closure& prepare_callback, | 71 const base::Closure& prepare_callback, |
| 42 const FetchCallback& fetch_callback) | 72 const FetchCallback& fetch_callback) |
| 43 : version_(version), | 73 : version_(version), |
| 74 net_log_(net_log), | |
| 44 prepare_callback_(prepare_callback), | 75 prepare_callback_(prepare_callback), |
| 45 fetch_callback_(fetch_callback), | 76 fetch_callback_(fetch_callback), |
| 46 request_(std::move(request)), | 77 request_(std::move(request)), |
| 47 resource_type_(resource_type), | 78 resource_type_(resource_type), |
| 48 weak_factory_(this) {} | 79 did_complete_(false), |
| 80 weak_factory_(this) { | |
| 81 std::string event_type = | |
|
horo
2016/06/25 05:49:56
nit:
const char*
or directly call in net::NetLog::
falken
2016/06/27 01:19:17
Done.
| |
| 82 ServiceWorkerMetrics::EventTypeToString(GetEventType()); | |
| 83 net_log_.BeginEvent(net::NetLog::TYPE_SERVICE_WORKER_DISPATCH_FETCH_EVENT, | |
| 84 net::NetLog::StringCallback("event_type", &event_type)); | |
| 85 } | |
| 49 | 86 |
| 50 ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {} | 87 ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() { |
| 88 if (!did_complete_) | |
| 89 net_log_.EndEvent(net::NetLog::TYPE_SERVICE_WORKER_DISPATCH_FETCH_EVENT); | |
| 90 } | |
| 51 | 91 |
| 52 void ServiceWorkerFetchDispatcher::Run() { | 92 void ServiceWorkerFetchDispatcher::Run() { |
| 53 DCHECK(version_->status() == ServiceWorkerVersion::ACTIVATING || | 93 DCHECK(version_->status() == ServiceWorkerVersion::ACTIVATING || |
| 54 version_->status() == ServiceWorkerVersion::ACTIVATED) | 94 version_->status() == ServiceWorkerVersion::ACTIVATED) |
| 55 << version_->status(); | 95 << version_->status(); |
| 56 | 96 |
| 57 if (version_->status() == ServiceWorkerVersion::ACTIVATING) { | 97 if (version_->status() == ServiceWorkerVersion::ACTIVATING) { |
| 98 net_log_.BeginEvent(net::NetLog::TYPE_SERVICE_WORKER_WAIT_FOR_ACTIVATION); | |
| 58 version_->RegisterStatusChangeCallback( | 99 version_->RegisterStatusChangeCallback( |
| 59 base::Bind(&ServiceWorkerFetchDispatcher::StartWorker, | 100 base::Bind(&ServiceWorkerFetchDispatcher::DidWaitForActivation, |
| 60 weak_factory_.GetWeakPtr())); | 101 weak_factory_.GetWeakPtr())); |
| 61 return; | 102 return; |
| 62 } | 103 } |
| 63 StartWorker(); | 104 StartWorker(); |
| 64 } | 105 } |
| 65 | 106 |
| 107 void ServiceWorkerFetchDispatcher::DidWaitForActivation() { | |
| 108 net_log_.EndEvent(net::NetLog::TYPE_SERVICE_WORKER_WAIT_FOR_ACTIVATION); | |
| 109 StartWorker(); | |
| 110 } | |
| 111 | |
| 66 void ServiceWorkerFetchDispatcher::StartWorker() { | 112 void ServiceWorkerFetchDispatcher::StartWorker() { |
| 67 // We might be REDUNDANT if a new worker started activating and kicked us out | 113 // We might be REDUNDANT if a new worker started activating and kicked us out |
| 68 // before we could finish activation. | 114 // before we could finish activation. |
| 69 if (version_->status() != ServiceWorkerVersion::ACTIVATED) { | 115 if (version_->status() != ServiceWorkerVersion::ACTIVATED) { |
| 70 DCHECK_EQ(ServiceWorkerVersion::REDUNDANT, version_->status()); | 116 DCHECK_EQ(ServiceWorkerVersion::REDUNDANT, version_->status()); |
| 71 DidFail(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED); | 117 DidFail(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED); |
| 72 return; | 118 return; |
| 73 } | 119 } |
| 120 | |
| 121 if (version_->running_status() == EmbeddedWorkerStatus::RUNNING) { | |
| 122 DispatchFetchEvent(); | |
| 123 return; | |
| 124 } | |
| 125 | |
| 126 net_log_.BeginEvent(net::NetLog::TYPE_SERVICE_WORKER_START_WORKER); | |
| 74 version_->RunAfterStartWorker( | 127 version_->RunAfterStartWorker( |
| 75 GetEventType(), | 128 GetEventType(), base::Bind(&ServiceWorkerFetchDispatcher::DidStartWorker, |
| 76 base::Bind(&ServiceWorkerFetchDispatcher::DispatchFetchEvent, | 129 weak_factory_.GetWeakPtr()), |
| 77 weak_factory_.GetWeakPtr()), | 130 base::Bind(&ServiceWorkerFetchDispatcher::DidFailToStartWorker, |
| 78 base::Bind(&ServiceWorkerFetchDispatcher::DidFail, | |
| 79 weak_factory_.GetWeakPtr())); | 131 weak_factory_.GetWeakPtr())); |
| 80 } | 132 } |
| 81 | 133 |
| 134 void ServiceWorkerFetchDispatcher::DidStartWorker() { | |
| 135 net_log_.EndEvent(net::NetLog::TYPE_SERVICE_WORKER_START_WORKER); | |
| 136 DispatchFetchEvent(); | |
| 137 } | |
| 138 | |
| 139 void ServiceWorkerFetchDispatcher::DidFailToStartWorker( | |
| 140 ServiceWorkerStatusCode status) { | |
| 141 EndNetLogEventWithServiceWorkerStatus( | |
| 142 net_log_, net::NetLog::TYPE_SERVICE_WORKER_START_WORKER, status); | |
| 143 DidFail(status); | |
| 144 } | |
| 145 | |
| 82 void ServiceWorkerFetchDispatcher::DispatchFetchEvent() { | 146 void ServiceWorkerFetchDispatcher::DispatchFetchEvent() { |
| 83 DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status()) | 147 DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status()) |
| 84 << "Worker stopped too soon after it was started."; | 148 << "Worker stopped too soon after it was started."; |
| 85 | 149 |
| 86 DCHECK(!prepare_callback_.is_null()); | 150 DCHECK(!prepare_callback_.is_null()); |
| 87 base::Closure prepare_callback = prepare_callback_; | 151 base::Closure prepare_callback = prepare_callback_; |
| 88 prepare_callback.Run(); | 152 prepare_callback.Run(); |
| 89 | 153 |
| 154 net_log_.BeginEvent(net::NetLog::TYPE_SERVICE_WORKER_FETCH_EVENT); | |
| 90 int request_id = version_->StartRequest( | 155 int request_id = version_->StartRequest( |
| 91 GetEventType(), base::Bind(&ServiceWorkerFetchDispatcher::DidFail, | 156 GetEventType(), |
| 92 weak_factory_.GetWeakPtr())); | 157 base::Bind(&ServiceWorkerFetchDispatcher::DidFailToDispatch, |
| 158 weak_factory_.GetWeakPtr())); | |
| 93 version_->DispatchEvent<ServiceWorkerHostMsg_FetchEventFinished>( | 159 version_->DispatchEvent<ServiceWorkerHostMsg_FetchEventFinished>( |
| 94 request_id, ServiceWorkerMsg_FetchEvent(request_id, *request_.get()), | 160 request_id, ServiceWorkerMsg_FetchEvent(request_id, *request_.get()), |
| 95 base::Bind(&ServiceWorkerFetchDispatcher::DidFinish, | 161 base::Bind(&ServiceWorkerFetchDispatcher::DidFinish, |
| 96 weak_factory_.GetWeakPtr())); | 162 weak_factory_.GetWeakPtr())); |
| 97 } | 163 } |
| 98 | 164 |
| 99 void ServiceWorkerFetchDispatcher::DidPrepare() { | 165 void ServiceWorkerFetchDispatcher::DidFailToDispatch( |
| 100 DCHECK(!prepare_callback_.is_null()); | 166 ServiceWorkerStatusCode status) { |
| 101 base::Closure prepare_callback = prepare_callback_; | 167 EndNetLogEventWithServiceWorkerStatus( |
| 102 prepare_callback.Run(); | 168 net_log_, net::NetLog::TYPE_SERVICE_WORKER_FETCH_EVENT, status); |
| 169 DidFail(status); | |
| 103 } | 170 } |
| 104 | 171 |
| 105 void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) { | 172 void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) { |
| 106 DCHECK(!fetch_callback_.is_null()); | 173 DCHECK_NE(SERVICE_WORKER_OK, status); |
| 107 FetchCallback fetch_callback = fetch_callback_; | 174 Complete(status, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
| 108 scoped_refptr<ServiceWorkerVersion> version = version_; | 175 ServiceWorkerResponse()); |
| 109 fetch_callback.Run(status, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, | |
| 110 ServiceWorkerResponse(), version); | |
| 111 } | 176 } |
| 112 | 177 |
| 113 void ServiceWorkerFetchDispatcher::DidFinish( | 178 void ServiceWorkerFetchDispatcher::DidFinish( |
| 114 int request_id, | 179 int request_id, |
| 115 ServiceWorkerFetchEventResult fetch_result, | 180 ServiceWorkerFetchEventResult fetch_result, |
| 116 const ServiceWorkerResponse& response) { | 181 const ServiceWorkerResponse& response) { |
| 182 net_log_.EndEvent(net::NetLog::TYPE_SERVICE_WORKER_FETCH_EVENT); | |
| 183 | |
| 117 const bool handled = | 184 const bool handled = |
| 118 (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE); | 185 (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE); |
| 119 if (!version_->FinishRequest(request_id, handled)) | 186 if (!version_->FinishRequest(request_id, handled)) |
| 120 NOTREACHED() << "Should only receive one reply per event"; | 187 NOTREACHED() << "Should only receive one reply per event"; |
| 121 | 188 |
| 189 Complete(SERVICE_WORKER_OK, fetch_result, response); | |
| 190 } | |
| 191 | |
| 192 void ServiceWorkerFetchDispatcher::Complete( | |
| 193 ServiceWorkerStatusCode status, | |
| 194 ServiceWorkerFetchEventResult fetch_result, | |
| 195 const ServiceWorkerResponse& response) { | |
| 122 DCHECK(!fetch_callback_.is_null()); | 196 DCHECK(!fetch_callback_.is_null()); |
| 197 | |
| 198 did_complete_ = true; | |
| 199 net_log_.EndEvent( | |
| 200 net::NetLog::TYPE_SERVICE_WORKER_DISPATCH_FETCH_EVENT, | |
| 201 base::Bind(&NetLogFetchEventCallback, status, fetch_result)); | |
| 202 | |
| 123 FetchCallback fetch_callback = fetch_callback_; | 203 FetchCallback fetch_callback = fetch_callback_; |
| 124 scoped_refptr<ServiceWorkerVersion> version = version_; | 204 scoped_refptr<ServiceWorkerVersion> version = version_; |
| 125 fetch_callback.Run(SERVICE_WORKER_OK, fetch_result, response, version); | 205 fetch_callback.Run(status, fetch_result, response, version); |
| 126 } | 206 } |
| 127 | 207 |
| 128 ServiceWorkerMetrics::EventType ServiceWorkerFetchDispatcher::GetEventType() | 208 ServiceWorkerMetrics::EventType ServiceWorkerFetchDispatcher::GetEventType() |
| 129 const { | 209 const { |
| 130 if (request_->fetch_type == ServiceWorkerFetchType::FOREIGN_FETCH) | 210 if (request_->fetch_type == ServiceWorkerFetchType::FOREIGN_FETCH) |
| 131 return ServiceWorkerMetrics::EventType::FOREIGN_FETCH; | 211 return ServiceWorkerMetrics::EventType::FOREIGN_FETCH; |
| 132 return ResourceTypeToEventType(resource_type_); | 212 return ResourceTypeToEventType(resource_type_); |
| 133 } | 213 } |
| 134 | 214 |
| 135 } // namespace content | 215 } // namespace content |
| OLD | NEW |