Index: content/browser/service_worker/service_worker_dispatcher_host.cc |
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc |
index ec8c364d17a2170ad1023140dfc6eacbd4c17d2a..b2c5c23d9b52db1f012f839213331ee4a1f883e3 100644 |
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc |
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc |
@@ -10,11 +10,13 @@ |
#include "base/macros.h" |
#include "base/profiler/scoped_tracker.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "base/thread_task_runner_handle.h" |
#include "base/trace_event/trace_event.h" |
#include "content/browser/bad_message.h" |
#include "content/browser/message_port_message_filter.h" |
#include "content/browser/message_port_service.h" |
#include "content/browser/service_worker/embedded_worker_registry.h" |
+#include "content/browser/service_worker/service_worker_client_utils.h" |
#include "content/browser/service_worker/service_worker_context_core.h" |
#include "content/browser/service_worker/service_worker_context_wrapper.h" |
#include "content/browser/service_worker/service_worker_handle.h" |
@@ -51,6 +53,11 @@ const uint32_t kFilteredMessageClasses[] = { |
ServiceWorkerMsgStart, EmbeddedWorkerMsgStart, |
}; |
+void RunSoon(const base::Closure& callback) { |
+ if (!callback.is_null()) |
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); |
+} |
+ |
bool CanUnregisterServiceWorker(const GURL& document_url, |
const GURL& pattern) { |
DCHECK(document_url.is_valid()); |
@@ -694,9 +701,40 @@ void ServiceWorkerDispatcherHost::OnPostMessageToWorker( |
return; |
} |
- handle->version()->DispatchExtendableMessageEvent( |
- sender_provider_host, message, source_origin, sent_message_ports, |
- base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
+ for (const TransferredMessagePort& port : sent_message_ports) |
+ MessagePortService::GetInstance()->HoldMessages(port.id); |
+ |
+ switch (sender_provider_host->provider_type()) { |
+ case SERVICE_WORKER_PROVIDER_FOR_WINDOW: |
+ case SERVICE_WORKER_PROVIDER_FOR_WORKER: |
+ case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER: |
+ service_worker_client_utils::GetClient( |
+ sender_provider_host, |
+ base::Bind( |
+ &ServiceWorkerDispatcherHost::DispatchExtendableMessageEvent< |
+ ServiceWorkerClientInfo>, |
+ this, make_scoped_refptr(handle->version()), message, |
+ source_origin, sent_message_ports)); |
+ break; |
+ case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER: |
+ // TODO(nhiroki): Decrement a reference to ServiceWorkerHandle if starting |
+ // worker fails (http://crbug.com/543198). |
+ RunSoon(base::Bind( |
+ &ServiceWorkerDispatcherHost::DispatchExtendableMessageEvent< |
+ ServiceWorkerObjectInfo>, |
+ this, make_scoped_refptr(handle->version()), message, source_origin, |
+ sent_message_ports, |
+ sender_provider_host->GetOrCreateServiceWorkerHandle( |
+ sender_provider_host->running_hosted_version()))); |
+ break; |
+ case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME: |
+ case SERVICE_WORKER_PROVIDER_UNKNOWN: |
+ NOTREACHED() << sender_provider_host->provider_type(); |
+ RunSoon(base::Bind( |
+ &ServiceWorkerDispatcherHost::DidFailToDispatchExtendableMessageEvent, |
+ this, sent_message_ports, SERVICE_WORKER_ERROR_FAILED)); |
falken
2016/03/15 07:29:16
Should we bother handling this after NOTREACHED? P
nhiroki
2016/03/15 07:57:25
Good point. Yes, we don't have to handle the case.
|
+ break; |
+ } |
} |
void ServiceWorkerDispatcherHost::OnDeprecatedPostMessageToWorker( |
@@ -830,6 +868,72 @@ void ServiceWorkerDispatcherHost::OnSetHostedVersionId(int provider_id, |
provider_id, info, attrs)); |
} |
+template <typename SourceInfo> |
+void ServiceWorkerDispatcherHost::DispatchExtendableMessageEvent( |
+ scoped_refptr<ServiceWorkerVersion> worker, |
+ const base::string16& message, |
+ const url::Origin& source_origin, |
+ const std::vector<TransferredMessagePort>& sent_message_ports, |
+ const SourceInfo& source_info) { |
+ if (!source_info.IsValid()) { |
+ DidFailToDispatchExtendableMessageEvent(sent_message_ports, |
+ SERVICE_WORKER_ERROR_FAILED); |
+ return; |
+ } |
+ worker->RunAfterStartWorker( |
+ base::Bind(&ServiceWorkerDispatcherHost:: |
+ DispatchExtendableMessageEventAfterStartWorker, |
+ this, worker, message, source_origin, sent_message_ports, |
+ ExtendableMessageEventSource(source_info)), |
+ base::Bind( |
+ &ServiceWorkerDispatcherHost::DidFailToDispatchExtendableMessageEvent, |
+ this, sent_message_ports)); |
+} |
+ |
+void ServiceWorkerDispatcherHost:: |
+ DispatchExtendableMessageEventAfterStartWorker( |
+ scoped_refptr<ServiceWorkerVersion> worker, |
+ const base::string16& message, |
+ const url::Origin& source_origin, |
+ const std::vector<TransferredMessagePort>& sent_message_ports, |
+ const ExtendableMessageEventSource& source) { |
+ int request_id = |
+ worker->StartRequest(ServiceWorkerMetrics::EventType::MESSAGE, |
+ base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
+ |
+ MessagePortMessageFilter* filter = |
+ worker->embedded_worker()->message_port_message_filter(); |
+ std::vector<int> new_routing_ids; |
+ filter->UpdateMessagePortsWithNewRoutes(sent_message_ports, &new_routing_ids); |
+ |
+ ServiceWorkerMsg_ExtendableMessageEvent_Params params; |
+ params.message = message; |
+ params.source_origin = source_origin; |
+ params.message_ports = sent_message_ports; |
+ params.new_routing_ids = new_routing_ids; |
+ params.source = source; |
+ |
+ // Hide the client url if the client has a unique origin. |
+ if (source_origin.unique()) { |
+ if (params.source.client_info.IsValid()) |
+ params.source.client_info.url = GURL(); |
+ else |
+ params.source.service_worker_info.url = GURL(); |
+ } |
+ |
+ worker->DispatchSimpleEvent< |
+ ServiceWorkerHostMsg_ExtendableMessageEventFinished>( |
+ request_id, ServiceWorkerMsg_ExtendableMessageEvent(request_id, params)); |
+} |
+ |
+void ServiceWorkerDispatcherHost::DidFailToDispatchExtendableMessageEvent( |
+ const std::vector<TransferredMessagePort>& sent_message_ports, |
+ ServiceWorkerStatusCode status) { |
+ // Transfering the message ports failed, so destroy the ports. |
+ for (const TransferredMessagePort& port : sent_message_ports) |
+ MessagePortService::GetInstance()->ClosePort(port.id); |
+} |
+ |
ServiceWorkerRegistrationHandle* |
ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id, |
int64_t registration_id) { |