Chromium Code Reviews| Index: content/renderer/service_worker/service_worker_context_client.cc |
| diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc |
| index ab400ee2f4ffc7356a21373c6772a8e7f50a2e0a..e1ad567d7277beab701802102ef4c9412c6c6e8a 100644 |
| --- a/content/renderer/service_worker/service_worker_context_client.cc |
| +++ b/content/renderer/service_worker/service_worker_context_client.cc |
| @@ -4,6 +4,7 @@ |
| #include "content/renderer/service_worker/service_worker_context_client.h" |
| +#include <map> |
| #include <memory> |
| #include <utility> |
| @@ -110,6 +111,20 @@ class WebServiceWorkerNetworkProviderImpl |
| std::unique_ptr<ServiceWorkerNetworkProvider> provider_; |
| }; |
| +class StreamHandleListener |
| + : public blink::WebServiceWorkerStreamHandle::Listener { |
| + public: |
| + StreamHandleListener( |
| + blink::mojom::ServiceWorkerStreamCallbackPtr callback_ptr) |
| + : callback_ptr_(std::move(callback_ptr)) {} |
| + |
| + void OnAborted() override { callback_ptr_->OnAborted(); } |
| + void OnCompleted() override { callback_ptr_->OnCompleted(); } |
| + |
| + private: |
| + blink::mojom::ServiceWorkerStreamCallbackPtr callback_ptr_; |
| +}; |
| + |
| ServiceWorkerStatusCode EventResultToStatus( |
| blink::WebServiceWorkerEventResult result) { |
| switch (result) { |
| @@ -219,7 +234,6 @@ void ToWebServiceWorkerResponse(const ServiceWorkerResponse& response, |
| web_response->setBlob(blink::WebString::fromASCII(response.blob_uuid), |
| response.blob_size); |
| } |
| - web_response->setStreamURL(blink::WebURL(response.stream_url)); |
| web_response->setError(response.error); |
| web_response->setResponseTime(response.response_time.ToInternalValue()); |
| if (response.is_in_cache_storage) { |
| @@ -244,11 +258,19 @@ void AbortPendingEventCallbacks(T& callbacks) { |
| } |
| } |
| +template <typename Key, typename Callback> |
| +void AbortPendingEventCallbacks(std::map<Key, Callback>& callbacks) { |
| + for (const auto& it : callbacks) |
| + it.second.Run(SERVICE_WORKER_ERROR_ABORT, base::Time::Now()); |
| +} |
| + |
| } // namespace |
| // Holding data that needs to be bound to the worker context on the |
| // worker thread. |
| struct ServiceWorkerContextClient::WorkerContextData { |
| + using SimpleEventCallback = |
| + base::Callback<void(ServiceWorkerStatusCode, base::Time)>; |
| using ClientsCallbacksMap = |
| IDMap<std::unique_ptr<blink::WebServiceWorkerClientsCallbacks>>; |
| using ClaimClientsCallbacksMap = |
| @@ -274,7 +296,6 @@ struct ServiceWorkerContextClient::WorkerContextData { |
| IDMap<std::unique_ptr<const DispatchNotificationCloseEventCallback>>; |
| using PushEventCallbacksMap = |
| IDMap<std::unique_ptr<const DispatchPushEventCallback>>; |
| - using FetchEventCallbacksMap = IDMap<std::unique_ptr<const FetchCallback>>; |
| using ExtendableMessageEventCallbacksMap = |
| IDMap<std::unique_ptr<const DispatchExtendableMessageEventCallback>>; |
| using NavigationPreloadRequestsMap = IDMap< |
| @@ -341,7 +362,12 @@ struct ServiceWorkerContextClient::WorkerContextData { |
| PushEventCallbacksMap push_event_callbacks; |
| // Pending callbacks for Fetch Events. |
| - FetchEventCallbacksMap fetch_event_callbacks; |
| + std::map<int /* fetch_event_id */, SimpleEventCallback> fetch_event_callbacks; |
| + |
| + // Pending callbacks for respondWith on each fetch event. |
| + std::map<int /* fetch_event_id */, |
| + mojom::ServiceWorkerFetchResponseCallbackPtr> |
| + fetch_response_callbacks; |
| // Pending callbacks for Extendable Message Events. |
| ExtendableMessageEventCallbacksMap message_event_callbacks; |
| @@ -859,33 +885,70 @@ void ServiceWorkerContextClient::didHandleInstallEvent( |
| void ServiceWorkerContextClient::respondToFetchEvent( |
| int fetch_event_id, |
| double event_dispatch_time) { |
| - Send(new ServiceWorkerHostMsg_FetchEventResponse( |
| - GetRoutingID(), fetch_event_id, |
| - SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, ServiceWorkerResponse(), |
| - base::Time::FromDoubleT(event_dispatch_time))); |
| + const mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback = |
| + context_->fetch_response_callbacks[fetch_event_id]; |
| + DCHECK(response_callback.is_bound()); |
| + response_callback->OnFallback(base::Time::FromDoubleT(event_dispatch_time)); |
| + context_->fetch_response_callbacks.erase(fetch_event_id); |
| } |
| -void ServiceWorkerContextClient::respondToFetchEvent( |
| +void ServiceWorkerContextClient::respondToFetchEventWithResponse( |
| int fetch_event_id, |
| const blink::WebServiceWorkerResponse& web_response, |
| double event_dispatch_time) { |
| - Send(new ServiceWorkerHostMsg_FetchEventResponse( |
| - GetRoutingID(), fetch_event_id, |
| - SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE, |
| - GetServiceWorkerResponseFromWebResponse(web_response), |
| - base::Time::FromDoubleT(event_dispatch_time))); |
| + ServiceWorkerResponse response( |
| + GetServiceWorkerResponseFromWebResponse(web_response)); |
| + const mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback = |
| + context_->fetch_response_callbacks[fetch_event_id]; |
| + if (response.blob_uuid.size()) { |
| + // Send the legacy IPC due to the ordering issue between respondWith and |
| + // blob. |
| + // TODO(shimazu): mojofy this IPC after blob starts using sync IPC for |
| + // creation or is mojofied. |
|
horo
2017/04/06 05:22:09
we should have crbug ID.
shimazu
2017/04/07 08:52:29
Done.
|
| + Send(new ServiceWorkerHostMsg_FetchEventResponse( |
| + GetRoutingID(), fetch_event_id, response, |
| + base::Time::FromDoubleT(event_dispatch_time))); |
| + } else { |
| + response_callback->OnResponse(response, |
| + base::Time::FromDoubleT(event_dispatch_time)); |
| + } |
| + context_->fetch_response_callbacks.erase(fetch_event_id); |
| +} |
| + |
| +void ServiceWorkerContextClient::respondToFetchEventWithResponseStream( |
| + int fetch_event_id, |
| + const blink::WebServiceWorkerResponse& web_response, |
| + blink::WebServiceWorkerStreamHandle* web_stream_handle, |
| + double event_dispatch_time) { |
| + ServiceWorkerResponse response( |
| + GetServiceWorkerResponseFromWebResponse(web_response)); |
| + const mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback = |
| + context_->fetch_response_callbacks[fetch_event_id]; |
| + blink::mojom::ServiceWorkerStreamHandlePtr stream_handle = |
| + blink::mojom::ServiceWorkerStreamHandle::New(); |
| + blink::mojom::ServiceWorkerStreamCallbackPtr callback_ptr; |
| + stream_handle->callback_request = mojo::MakeRequest(&callback_ptr); |
| + stream_handle->stream = web_stream_handle->drainStreamDataPipe(); |
| + |
| + web_stream_handle->setListener( |
| + base::MakeUnique<StreamHandleListener>(std::move(callback_ptr))); |
| + |
| + response_callback->OnResponseStream( |
| + response, std::move(stream_handle), |
| + base::Time::FromDoubleT(event_dispatch_time)); |
| + context_->fetch_response_callbacks.erase(fetch_event_id); |
| } |
| void ServiceWorkerContextClient::didHandleFetchEvent( |
| int fetch_event_id, |
| blink::WebServiceWorkerEventResult result, |
| double event_dispatch_time) { |
| - const FetchCallback* callback = |
| - context_->fetch_event_callbacks.Lookup(fetch_event_id); |
| + const WorkerContextData::SimpleEventCallback& callback = |
| + context_->fetch_event_callbacks[fetch_event_id]; |
| DCHECK(callback); |
| - callback->Run(EventResultToStatus(result), |
| - base::Time::FromDoubleT(event_dispatch_time)); |
| - context_->fetch_event_callbacks.Remove(fetch_event_id); |
| + callback.Run(EventResultToStatus(result), |
| + base::Time::FromDoubleT(event_dispatch_time)); |
| + context_->fetch_event_callbacks.erase(fetch_event_id); |
| } |
| void ServiceWorkerContextClient::didHandleNotificationClickEvent( |
| @@ -1235,6 +1298,7 @@ void ServiceWorkerContextClient::DispatchFetchEvent( |
| int fetch_event_id, |
| const ServiceWorkerFetchRequest& request, |
| mojom::FetchEventPreloadHandlePtr preload_handle, |
| + mojom::ServiceWorkerFetchResponseCallbackPtr response_callback, |
| const DispatchFetchEventCallback& callback) { |
| std::unique_ptr<NavigationPreloadRequest> preload_request = |
| preload_handle |
| @@ -1244,8 +1308,10 @@ void ServiceWorkerContextClient::DispatchFetchEvent( |
| const bool navigation_preload_sent = !!preload_request; |
| TRACE_EVENT0("ServiceWorker", |
| "ServiceWorkerContextClient::DispatchFetchEvent"); |
| - context_->fetch_event_callbacks.AddWithID( |
| - base::MakeUnique<FetchCallback>(callback), fetch_event_id); |
| + context_->fetch_response_callbacks.insert( |
| + std::make_pair(fetch_event_id, std::move(response_callback))); |
| + context_->fetch_event_callbacks.insert( |
| + std::make_pair(fetch_event_id, std::move(callback))); |
| if (preload_request) { |
| context_->preload_requests.AddWithID(std::move(preload_request), |
| fetch_event_id); |