Index: content/browser/service_worker/service_worker_fetch_dispatcher.cc |
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc |
index 26fadcacb3e1268133f1d822838883c9c947b519..e0b19e8feec0c277b37461a931ad08eb82ae1699 100644 |
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc |
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc |
@@ -280,30 +280,96 @@ ServiceWorkerMetrics::EventType FetchTypeToWaitUntilEventType( |
// Helper to receive the fetch event response even if |
// ServiceWorkerFetchDispatcher has been destroyed. |
-class ServiceWorkerFetchDispatcher::ResponseCallback { |
+class ServiceWorkerFetchDispatcher::ResponseCallback |
+ : public mojom::ServiceWorkerFetchResponseReceiver { |
public: |
ResponseCallback(base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher, |
- ServiceWorkerVersion* version) |
- : fetch_dispatcher_(fetch_dispatcher), version_(version) {} |
+ ServiceWorkerVersion* version, |
+ int fetch_event_id) |
+ : fetch_dispatcher_(fetch_dispatcher), |
+ version_(version), |
+ fetch_event_id_(fetch_event_id), |
+ binding_(this) { |
+ // LOG(ERROR) << "ResponseCallback " << this; |
+ } |
+ ~ResponseCallback() override { |
+ // LOG(ERROR) << "~ResponseCallback " << this; |
+ } |
void Run(int request_id, |
- ServiceWorkerFetchEventResult fetch_result, |
const ServiceWorkerResponse& response, |
base::Time dispatch_event_time) { |
- const bool handled = |
- (fetch_result == SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE); |
- if (!version_->FinishRequest(request_id, handled, dispatch_event_time)) |
+ // Legacy IPC callback for blob handling. |
+ // LOG(ERROR) << "ResponseCallback::Run() " << this; |
+ DCHECK_EQ(fetch_event_id_, request_id); |
+ DCHECK(response.blob_uuid.size()); |
+ if (!version_->FinishRequest(request_id, true, dispatch_event_time)) |
NOTREACHED() << "Should only receive one reply per event"; |
// |fetch_dispatcher| is null if the URLRequest was killed. |
if (fetch_dispatcher_) |
- fetch_dispatcher_->DidFinish(request_id, fetch_result, response); |
+ fetch_dispatcher_->DidFinish( |
+ request_id, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, response, |
+ mojo::ScopedDataPipeConsumerHandle()); |
+ } |
+ |
+ void OnResponse(const ServiceWorkerResponse& response, |
+ base::Time dispatch_event_time) override { |
+ // LOG(ERROR) << "ResponseCallback::OnResponse() " << this; |
+ // Protects |fetch_dispatcher_|. |
+ base::WeakPtr<ServiceWorkerFetchDispatcher> dispatcher(fetch_dispatcher_); |
+ const int event_id(fetch_event_id_); |
+ // FinishRequest() will delete |this|. |
+ if (!version_->FinishRequest(fetch_event_id_, true, dispatch_event_time)) |
+ NOTREACHED() << "Should only receive one reply per event"; |
+ // |dispatcher| is null if the URLRequest was killed. |
+ if (!dispatcher) |
+ return; |
+ dispatcher->DidFinish(event_id, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, |
+ response, mojo::ScopedDataPipeConsumerHandle()); |
+ } |
+ void OnResponseStream(const ServiceWorkerResponse& response, |
+ mojo::ScopedDataPipeConsumerHandle stream, |
+ base::Time dispatch_event_time) override { |
+ // LOG(ERROR) << "ResponseCallback::OnResponseStream() " << this; |
+ // TODO(horo): Pass stream. |
+ // Protects |fetch_dispatcher_|. |
+ base::WeakPtr<ServiceWorkerFetchDispatcher> dispatcher(fetch_dispatcher_); |
+ const int event_id(fetch_event_id_); |
+ // FinishRequest() will delete |this|. |
+ if (!version_->FinishRequest(fetch_event_id_, true, dispatch_event_time)) |
+ NOTREACHED() << "Should only receive one reply per event"; |
+ // |dispatcher| is null if the URLRequest was killed. |
+ if (!dispatcher) |
+ return; |
+ dispatcher->DidFinish(event_id, SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, |
+ response, std::move(stream)); |
+ } |
+ void OnFallback(base::Time dispatch_event_time) override { |
+ // LOG(ERROR) << "ResponseCallback::OnFallback() " << this; |
+ // Protects |fetch_dispatcher_|. |
+ base::WeakPtr<ServiceWorkerFetchDispatcher> dispatcher(fetch_dispatcher_); |
+ const int event_id(fetch_event_id_); |
+ // FinishRequest() will delete |this|. |
+ if (!version_->FinishRequest(fetch_event_id_, false, dispatch_event_time)) |
+ NOTREACHED() << "Should only receive one reply per event"; |
+ ServiceWorkerResponse response; |
+ // |dispatcher| is null if the URLRequest was killed. |
+ if (!dispatcher) |
+ return; |
+ dispatcher->DidFinish(event_id, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
+ response, mojo::ScopedDataPipeConsumerHandle()); |
+ } |
+ mojom::ServiceWorkerFetchResponseReceiverPtr Bind() { |
+ return binding_.CreateInterfacePtrAndBind(); |
} |
private: |
base::WeakPtr<ServiceWorkerFetchDispatcher> fetch_dispatcher_; |
// Owns |this|. |
ServiceWorkerVersion* version_; |
+ const int fetch_event_id_; |
+ mojo::Binding<mojom::ServiceWorkerFetchResponseReceiver> binding_; |
DISALLOW_COPY_AND_ASSIGN(ResponseCallback); |
}; |
@@ -451,8 +517,10 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() { |
base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
} |
- ResponseCallback* response_callback = |
- new ResponseCallback(weak_factory_.GetWeakPtr(), version_.get()); |
+ ResponseCallback* response_callback = new ResponseCallback( |
+ weak_factory_.GetWeakPtr(), version_.get(), fetch_event_id); |
+ mojom::ServiceWorkerFetchResponseReceiverPtr receiver( |
+ response_callback->Bind()); |
version_->RegisterRequestCallback<ServiceWorkerHostMsg_FetchEventResponse>( |
fetch_event_id, |
base::Bind(&ServiceWorkerFetchDispatcher::ResponseCallback::Run, |
@@ -472,6 +540,7 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() { |
// assets alive while the FetchEvent is ongoing in the service worker. |
version_->event_dispatcher()->DispatchFetchEvent( |
fetch_event_id, *request_, std::move(preload_handle_), |
+ std::move(receiver), |
base::Bind(&ServiceWorkerFetchDispatcher::OnFetchEventFinished, |
base::Unretained(version_.get()), event_finish_id, |
url_loader_assets_)); |
@@ -487,21 +556,23 @@ void ServiceWorkerFetchDispatcher::DidFailToDispatch( |
void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) { |
DCHECK_NE(SERVICE_WORKER_OK, status); |
Complete(status, SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
- ServiceWorkerResponse()); |
+ ServiceWorkerResponse(), mojo::ScopedDataPipeConsumerHandle()); |
} |
void ServiceWorkerFetchDispatcher::DidFinish( |
int request_id, |
ServiceWorkerFetchEventResult fetch_result, |
- const ServiceWorkerResponse& response) { |
+ const ServiceWorkerResponse& response, |
+ mojo::ScopedDataPipeConsumerHandle stream) { |
net_log_.EndEvent(net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT); |
- Complete(SERVICE_WORKER_OK, fetch_result, response); |
+ Complete(SERVICE_WORKER_OK, fetch_result, response, std::move(stream)); |
} |
void ServiceWorkerFetchDispatcher::Complete( |
ServiceWorkerStatusCode status, |
ServiceWorkerFetchEventResult fetch_result, |
- const ServiceWorkerResponse& response) { |
+ const ServiceWorkerResponse& response, |
+ mojo::ScopedDataPipeConsumerHandle stream) { |
DCHECK(!fetch_callback_.is_null()); |
did_complete_ = true; |
@@ -511,7 +582,8 @@ void ServiceWorkerFetchDispatcher::Complete( |
FetchCallback fetch_callback = fetch_callback_; |
scoped_refptr<ServiceWorkerVersion> version = version_; |
- fetch_callback.Run(status, fetch_result, response, version); |
+ fetch_callback.Run(status, fetch_result, response, std::move(stream), |
+ version); |
} |
bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload( |