summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 01:48:09 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 01:48:09 +0000
commit76ad75fcb6fbe47b411d51ce4756c4acbbc289b2 (patch)
treee2b631c661014a2e9881a1e70467d1c4c72b9837
parent5e2363171267ae9bca5fe39627123edd57147a71 (diff)
downloadchromium_src-76ad75fcb6fbe47b411d51ce4756c4acbbc289b2.zip
chromium_src-76ad75fcb6fbe47b411d51ce4756c4acbbc289b2.tar.gz
chromium_src-76ad75fcb6fbe47b411d51ce4756c4acbbc289b2.tar.bz2
Chromium-side plumbing for ServiceWorker -> Document postMessage (2/3)
This is one of multi-sided patches for postMessage plumbing: 1/3: https://codereview.chromium.org/263143004/ (blink) 2/3: THIS PATCH 3/3: https://codereview.chromium.org/264233003/ (blink, adds Layout test) BUG=366063 TEST=to be added in the patch 3/3 R=jochen@chromium.org, jsbell@chromium.org, marja@chromium.org, tsepez@chromium.org Review URL: https://codereview.chromium.org/246023007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269143 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/message_port_message_filter.cc16
-rw-r--r--content/browser/message_port_message_filter.h6
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.cc22
-rw-r--r--content/browser/service_worker/service_worker_dispatcher_host.h8
-rw-r--r--content/browser/service_worker/service_worker_provider_host.cc20
-rw-r--r--content/browser/service_worker/service_worker_provider_host.h5
-rw-r--r--content/browser/service_worker/service_worker_version.cc16
-rw-r--r--content/browser/service_worker/service_worker_version.h3
-rw-r--r--content/browser/web_contents/web_contents_impl.cc12
-rw-r--r--content/child/service_worker/service_worker_dispatcher.cc34
-rw-r--r--content/child/service_worker/service_worker_dispatcher.h6
-rw-r--r--content/child/service_worker/web_service_worker_impl.cc2
-rw-r--r--content/common/service_worker/service_worker_messages.h20
-rw-r--r--content/renderer/service_worker/embedded_worker_context_client.cc11
-rw-r--r--content/renderer/service_worker/embedded_worker_context_client.h5
-rw-r--r--content/renderer/service_worker/service_worker_script_context.cc32
-rw-r--r--content/renderer/service_worker/service_worker_script_context.h4
17 files changed, 195 insertions, 27 deletions
diff --git a/content/browser/message_port_message_filter.cc b/content/browser/message_port_message_filter.cc
index 4fd8045..6de26bd 100644
--- a/content/browser/message_port_message_filter.cc
+++ b/content/browser/message_port_message_filter.cc
@@ -57,6 +57,22 @@ int MessagePortMessageFilter::GetNextRoutingID() {
return next_routing_id_.Run();
}
+void MessagePortMessageFilter::UpdateMessagePortsWithNewRoutes(
+ const std::vector<int>& message_port_ids,
+ std::vector<int>* new_routing_ids) {
+ DCHECK(new_routing_ids);
+ new_routing_ids->clear();
+ new_routing_ids->resize(message_port_ids.size());
+
+ for (size_t i = 0; i < message_port_ids.size(); ++i) {
+ (*new_routing_ids)[i] = GetNextRoutingID();
+ MessagePortService::GetInstance()->UpdateMessagePort(
+ message_port_ids[i],
+ this,
+ (*new_routing_ids)[i]);
+ }
+}
+
void MessagePortMessageFilter::OnCreateMessagePort(int *route_id,
int* message_port_id) {
*route_id = next_routing_id_.Run();
diff --git a/content/browser/message_port_message_filter.h b/content/browser/message_port_message_filter.h
index 5cc191e..a324ad8 100644
--- a/content/browser/message_port_message_filter.h
+++ b/content/browser/message_port_message_filter.h
@@ -29,6 +29,12 @@ class CONTENT_EXPORT MessagePortMessageFilter : public BrowserMessageFilter {
int GetNextRoutingID();
+ // Updates message ports registered for |message_port_ids| and returns
+ // new routing IDs for the updated ports via |new_routing_ids|.
+ void UpdateMessagePortsWithNewRoutes(
+ const std::vector<int>& message_port_ids,
+ std::vector<int>* new_routing_ids);
+
protected:
// This is protected, so we can define sub classes for testing.
virtual ~MessagePortMessageFilter();
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc
index 0ddaaf1..ded0a37 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -100,8 +100,8 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
OnProviderDestroyed)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SetVersionId,
OnSetHostedVersionId)
- IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessage,
- OnPostMessage)
+ IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker,
+ OnPostMessageToWorker)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoaded,
OnWorkerScriptLoaded)
IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_WorkerScriptLoadFailed,
@@ -224,30 +224,26 @@ void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(
request_id));
}
-void ServiceWorkerDispatcherHost::OnPostMessage(
+void ServiceWorkerDispatcherHost::OnPostMessageToWorker(
int handle_id,
const base::string16& message,
const std::vector<int>& sent_message_port_ids) {
if (!context_ || !ServiceWorkerUtils::IsFeatureEnabled())
return;
- std::vector<int> new_routing_ids(sent_message_port_ids.size());
- for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
- new_routing_ids[i] = message_port_message_filter_->GetNextRoutingID();
- MessagePortService::GetInstance()->UpdateMessagePort(
- sent_message_port_ids[i],
- message_port_message_filter_,
- new_routing_ids[i]);
- }
-
ServiceWorkerHandle* handle = handles_.Lookup(handle_id);
if (!handle) {
BadMessageReceived();
return;
}
+ std::vector<int> new_routing_ids;
+ message_port_message_filter_->UpdateMessagePortsWithNewRoutes(
+ sent_message_port_ids, &new_routing_ids);
handle->version()->SendMessage(
- ServiceWorkerMsg_Message(message, sent_message_port_ids, new_routing_ids),
+ ServiceWorkerMsg_MessageToWorker(message,
+ sent_message_port_ids,
+ new_routing_ids),
base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
}
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.h b/content/browser/service_worker/service_worker_dispatcher_host.h
index 952bfe0..7301eee 100644
--- a/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -47,6 +47,10 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
void RegisterServiceWorkerHandle(scoped_ptr<ServiceWorkerHandle> handle);
+ MessagePortMessageFilter* message_port_message_filter() {
+ return message_port_message_filter_;
+ }
+
protected:
virtual ~ServiceWorkerDispatcherHost();
@@ -86,6 +90,10 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
const std::vector<int>& sent_message_port_ids);
void OnIncrementServiceWorkerRefCount(int handle_id);
void OnDecrementServiceWorkerRefCount(int handle_id);
+ void OnPostMessageToWorker(int handle_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids);
+ void OnServiceWorkerObjectDestroyed(int handle_id);
// Callbacks from ServiceWorkerContextCore
void RegistrationComplete(int thread_id,
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc
index a2f3cd3..2da7d3e 100644
--- a/content/browser/service_worker/service_worker_provider_host.cc
+++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -5,6 +5,7 @@
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "base/stl_util.h"
+#include "content/browser/message_port_message_filter.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_request_handler.h"
#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
@@ -118,4 +119,23 @@ ServiceWorkerProviderHost::CreateRequestHandler(
return scoped_ptr<ServiceWorkerRequestHandler>();
}
+void ServiceWorkerProviderHost::PostMessage(
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids) {
+ if (!dispatcher_host_)
+ return; // Could be NULL in some tests.
+
+ std::vector<int> new_routing_ids;
+ dispatcher_host_->message_port_message_filter()->
+ UpdateMessagePortsWithNewRoutes(sent_message_port_ids,
+ &new_routing_ids);
+
+ dispatcher_host_->Send(
+ new ServiceWorkerMsg_MessageToDocument(
+ kDocumentMainThreadId, provider_id(),
+ message,
+ sent_message_port_ids,
+ new_routing_ids));
+}
+
} // namespace content
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h
index d0adae3..5aceebf 100644
--- a/content/browser/service_worker/service_worker_provider_host.h
+++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
#include <set>
+#include <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -83,6 +84,10 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
scoped_ptr<ServiceWorkerRequestHandler> CreateRequestHandler(
ResourceType::Type resource_type);
+ // Dispatches message event to the document.
+ void PostMessage(const base::string16& message,
+ const std::vector<int>& sent_message_port_ids);
+
private:
const int process_id_;
const int provider_id_;
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 77e01c1..66ca883 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -6,6 +6,7 @@
#include "base/command_line.h"
#include "base/stl_util.h"
+#include "base/strings/string16.h"
#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/service_worker_context_core.h"
@@ -429,6 +430,8 @@ bool ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) {
OnFetchEventFinished)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_SyncEventFinished,
OnSyncEventFinished)
+ IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToDocument,
+ OnPostMessageToDocument)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -561,4 +564,17 @@ int64 ServiceWorkerVersion::LookupInScriptCache(const GURL& url) {
return found->second;
}
+void ServiceWorkerVersion::OnPostMessageToDocument(
+ int client_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids) {
+ ServiceWorkerProviderHost* provider_host =
+ controllee_by_id_.Lookup(client_id);
+ if (!provider_host) {
+ // The client may already have been closed, just ignore.
+ return;
+ }
+ provider_host->PostMessage(message, sent_message_port_ids);
+}
+
} // namespace content
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 3329844..84ecc01 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -240,6 +240,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
ServiceWorkerFetchEventResult result,
const ServiceWorkerResponse& response);
void OnSyncEventFinished(int request_id);
+ void OnPostMessageToDocument(int client_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids);
const int64 version_id_;
int64 registration_id_;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index f3ac8c14..c1b9be8 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3535,15 +3535,9 @@ void WebContentsImpl::RouteMessageEvent(
MessagePortMessageFilter* message_port_message_filter =
static_cast<RenderProcessHostImpl*>(GetRenderProcessHost())
->message_port_message_filter();
- std::vector<int> new_routing_ids(params.message_port_ids.size());
- for (size_t i = 0; i < params.message_port_ids.size(); ++i) {
- new_routing_ids[i] = message_port_message_filter->GetNextRoutingID();
- MessagePortService::GetInstance()->UpdateMessagePort(
- params.message_port_ids[i],
- message_port_message_filter,
- new_routing_ids[i]);
- }
- new_params.new_routing_ids = new_routing_ids;
+ message_port_message_filter->UpdateMessagePortsWithNewRoutes(
+ params.message_port_ids,
+ &new_params.new_routing_ids);
}
// If there is a source_routing_id, translate it to the routing ID for
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc
index 994acd7..123f983 100644
--- a/content/child/service_worker/service_worker_dispatcher.cc
+++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -7,10 +7,12 @@
#include "base/lazy_instance.h"
#include "base/stl_util.h"
#include "base/threading/thread_local.h"
+#include "content/child/child_thread.h"
#include "content/child/service_worker/service_worker_handle_reference.h"
#include "content/child/service_worker/service_worker_provider_context.h"
#include "content/child/service_worker/web_service_worker_impl.h"
#include "content/child/thread_safe_sender.h"
+#include "content/child/webmessageportchannel_impl.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
@@ -57,6 +59,8 @@ void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
OnServiceWorkerStateChanged)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetCurrentServiceWorker,
OnSetCurrentServiceWorker)
+ IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
+ OnPostMessage)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
DCHECK(handled) << "Unhandled message:" << msg.type();
@@ -231,6 +235,36 @@ void ServiceWorkerDispatcher::OnSetCurrentServiceWorker(
}
}
+void ServiceWorkerDispatcher::OnPostMessage(
+ int thread_id,
+ int provider_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids,
+ const std::vector<int>& new_routing_ids) {
+ // Make sure we're on the main document thread. (That must be the only
+ // thread we get this message)
+ DCHECK(ChildThread::current());
+
+ ScriptClientMap::iterator found = script_clients_.find(provider_id);
+ if (found == script_clients_.end()) {
+ // For now we do no queueing for messages sent to nonexistent / unattached
+ // client.
+ return;
+ }
+
+ std::vector<WebMessagePortChannelImpl*> ports;
+ if (!sent_message_port_ids.empty()) {
+ ports.resize(sent_message_port_ids.size());
+ for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
+ ports[i] = new WebMessagePortChannelImpl(
+ new_routing_ids[i], sent_message_port_ids[i],
+ base::MessageLoopProxy::current());
+ }
+ }
+
+ found->second->dispatchMessageEvent(message, ports);
+}
+
void ServiceWorkerDispatcher::AddServiceWorker(
int handle_id, WebServiceWorkerImpl* worker) {
DCHECK(!ContainsKey(service_workers_, handle_id));
diff --git a/content/child/service_worker/service_worker_dispatcher.h b/content/child/service_worker/service_worker_dispatcher.h
index 2c6ca3a..b596b37 100644
--- a/content/child/service_worker/service_worker_dispatcher.h
+++ b/content/child/service_worker/service_worker_dispatcher.h
@@ -6,6 +6,7 @@
#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_DISPATCHER_H_
#include <map>
+#include <vector>
#include "base/id_map.h"
#include "base/memory/ref_counted.h"
@@ -106,6 +107,11 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
void OnSetCurrentServiceWorker(int thread_id,
int provider_id,
const ServiceWorkerObjectInfo& info);
+ void OnPostMessage(int thread_id,
+ int provider_id,
+ const base::string16& message,
+ const std::vector<int>& sent_message_port_ids,
+ const std::vector<int>& new_routing_ids);
// Keeps map from handle_id to ServiceWorker object.
void AddServiceWorker(int handle_id, WebServiceWorkerImpl* worker);
diff --git a/content/child/service_worker/web_service_worker_impl.cc b/content/child/service_worker/web_service_worker_impl.cc
index 683cf74..d996dd6 100644
--- a/content/child/service_worker/web_service_worker_impl.cc
+++ b/content/child/service_worker/web_service_worker_impl.cc
@@ -95,7 +95,7 @@ blink::WebServiceWorkerState WebServiceWorkerImpl::state() const {
void WebServiceWorkerImpl::postMessage(const WebString& message,
WebMessagePortChannelArray* channels) {
- thread_safe_sender_->Send(new ServiceWorkerHostMsg_PostMessage(
+ thread_safe_sender_->Send(new ServiceWorkerHostMsg_PostMessageToWorker(
handle_ref_->handle_id(),
message,
WebMessagePortChannelImpl::ExtractMessagePortIDs(channels)));
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h
index 5337c6b..e3f2e38 100644
--- a/content/common/service_worker/service_worker_messages.h
+++ b/content/common/service_worker/service_worker_messages.h
@@ -67,8 +67,8 @@ IPC_MESSAGE_CONTROL4(ServiceWorkerHostMsg_UnregisterServiceWorker,
GURL /* scope (url pattern) */)
// Sends a 'message' event to a service worker (renderer->browser).
-IPC_MESSAGE_CONTROL3(ServiceWorkerHostMsg_PostMessage,
- int64 /* version_id */,
+IPC_MESSAGE_CONTROL3(ServiceWorkerHostMsg_PostMessageToWorker,
+ int /* handle_id */,
base::string16 /* message */,
std::vector<int> /* sent_message_port_ids */)
@@ -116,6 +116,12 @@ IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_SyncEventFinished,
IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_GetClientDocuments,
int /* request_id */)
+// Sends a 'message' event to a client document (renderer->browser).
+IPC_MESSAGE_ROUTED3(ServiceWorkerHostMsg_PostMessageToDocument,
+ int /* client_id */,
+ base::string16 /* message */,
+ std::vector<int> /* sent_message_port_ids */)
+
//---------------------------------------------------------------------------
// Messages sent from the browser to the child process.
//
@@ -156,6 +162,14 @@ IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_SetCurrentServiceWorker,
int /* provider_id */,
content::ServiceWorkerObjectInfo)
+// Sends a 'message' event to a client document (browser->renderer).
+IPC_MESSAGE_CONTROL5(ServiceWorkerMsg_MessageToDocument,
+ int /* thread_id */,
+ int /* provider_id */,
+ base::string16 /* message */,
+ std::vector<int> /* sent_message_port_ids */,
+ std::vector<int> /* new_routing_ids */)
+
// Sent via EmbeddedWorker to dispatch events.
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_InstallEvent,
int /* request_id */,
@@ -167,7 +181,7 @@ IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_FetchEvent,
content::ServiceWorkerFetchRequest)
IPC_MESSAGE_CONTROL1(ServiceWorkerMsg_SyncEvent,
int /* request_id */)
-IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_Message,
+IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_MessageToWorker,
base::string16 /* message */,
std::vector<int> /* sent_message_port_ids */,
std::vector<int> /* new_routing_ids */)
diff --git a/content/renderer/service_worker/embedded_worker_context_client.cc b/content/renderer/service_worker/embedded_worker_context_client.cc
index faff1da..4bd0635 100644
--- a/content/renderer/service_worker/embedded_worker_context_client.cc
+++ b/content/renderer/service_worker/embedded_worker_context_client.cc
@@ -11,6 +11,7 @@
#include "content/child/request_extra_data.h"
#include "content/child/service_worker/service_worker_network_provider.h"
#include "content/child/thread_safe_sender.h"
+#include "content/child/webmessageportchannel_impl.h"
#include "content/child/worker_task_runner.h"
#include "content/child/worker_thread_task_runner.h"
#include "content/common/devtools_messages.h"
@@ -286,6 +287,16 @@ EmbeddedWorkerContextClient::createServiceWorkerNetworkProvider(
return new WebServiceWorkerNetworkProviderImpl();
}
+void EmbeddedWorkerContextClient::postMessageToClient(
+ int client_id,
+ const blink::WebString& message,
+ blink::WebMessagePortChannelArray* channels) {
+ DCHECK(script_context_);
+ script_context_->PostMessageToDocument(
+ client_id, message,
+ WebMessagePortChannelImpl::ExtractMessagePortIDs(channels));
+}
+
void EmbeddedWorkerContextClient::OnMessageToWorker(
int thread_id,
int embedded_worker_id,
diff --git a/content/renderer/service_worker/embedded_worker_context_client.h b/content/renderer/service_worker/embedded_worker_context_client.h
index c7eefad..7d18ec5 100644
--- a/content/renderer/service_worker/embedded_worker_context_client.h
+++ b/content/renderer/service_worker/embedded_worker_context_client.h
@@ -93,6 +93,10 @@ class EmbeddedWorkerContextClient
virtual void didHandleSyncEvent(int request_id);
virtual blink::WebServiceWorkerNetworkProvider*
createServiceWorkerNetworkProvider(blink::WebDataSource* data_source);
+ virtual void postMessageToClient(
+ int client_id,
+ const blink::WebString& message,
+ blink::WebMessagePortChannelArray* channels);
// TODO: Implement DevTools related method overrides.
@@ -100,6 +104,7 @@ class EmbeddedWorkerContextClient
base::MessageLoopProxy* main_thread_proxy() const {
return main_thread_proxy_;
}
+ ThreadSafeSender* thread_safe_sender() { return sender_; }
private:
void OnMessageToWorker(int thread_id,
diff --git a/content/renderer/service_worker/service_worker_script_context.cc b/content/renderer/service_worker/service_worker_script_context.cc
index c97cd86..7df0808 100644
--- a/content/renderer/service_worker/service_worker_script_context.cc
+++ b/content/renderer/service_worker/service_worker_script_context.cc
@@ -5,6 +5,7 @@
#include "content/renderer/service_worker/service_worker_script_context.h"
#include "base/logging.h"
+#include "content/child/thread_safe_sender.h"
#include "content/child/webmessageportchannel_impl.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/renderer/service_worker/embedded_worker_context_client.h"
@@ -14,6 +15,20 @@
namespace content {
+namespace {
+
+void SendPostMessageToDocumentOnMainThread(
+ ThreadSafeSender* sender,
+ int routing_id,
+ int client_id,
+ const base::string16& message,
+ const std::vector<int>& message_port_ids) {
+ sender->Send(new ServiceWorkerHostMsg_PostMessageToDocument(
+ routing_id, client_id, message, message_port_ids));
+}
+
+} // namespace
+
ServiceWorkerScriptContext::ServiceWorkerScriptContext(
EmbeddedWorkerContextClient* embedded_context,
blink::WebServiceWorkerContextProxy* proxy)
@@ -31,7 +46,7 @@ void ServiceWorkerScriptContext::OnMessageReceived(
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_FetchEvent, OnFetchEvent)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_InstallEvent, OnInstallEvent)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SyncEvent, OnSyncEvent)
- IPC_MESSAGE_HANDLER(ServiceWorkerMsg_Message, OnPostMessage)
+ IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToWorker, OnPostMessage)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetClientDocuments,
OnDidGetClientDocuments)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -74,6 +89,21 @@ void ServiceWorkerScriptContext::GetClientDocuments(
GetRoutingID(), request_id));
}
+void ServiceWorkerScriptContext::PostMessageToDocument(
+ int client_id,
+ const base::string16& message,
+ const std::vector<int>& message_port_ids) {
+ // This may send IDs for MessagePorts, and all internal book-keeping
+ // messages for MessagePort (e.g. QueueMessages) are sent from main thread
+ // (with thread hopping), so we need to do the same thread hopping here not
+ // to overtake those messages.
+ embedded_context_->main_thread_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&SendPostMessageToDocumentOnMainThread,
+ make_scoped_refptr(embedded_context_->thread_safe_sender()),
+ GetRoutingID(), client_id, message, message_port_ids));
+}
+
void ServiceWorkerScriptContext::Send(IPC::Message* message) {
embedded_context_->Send(message);
}
diff --git a/content/renderer/service_worker/service_worker_script_context.h b/content/renderer/service_worker/service_worker_script_context.h
index 03a9e27..a528d34 100644
--- a/content/renderer/service_worker/service_worker_script_context.h
+++ b/content/renderer/service_worker/service_worker_script_context.h
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/id_map.h"
#include "base/strings/string16.h"
+#include "content/child/webmessageportchannel_impl.h"
#include "content/common/service_worker/service_worker_types.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerClientsInfo.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerEventResult.h"
@@ -49,6 +50,9 @@ class ServiceWorkerScriptContext {
void DidHandleSyncEvent(int request_id);
void GetClientDocuments(
blink::WebServiceWorkerClientsCallbacks* callbacks);
+ void PostMessageToDocument(int client_id,
+ const base::string16& message,
+ const std::vector<int>& message_port_ids);
private:
typedef IDMap<blink::WebServiceWorkerClientsCallbacks, IDMapOwnPointer>