diff options
Diffstat (limited to 'chromium/content/renderer/service_worker/service_worker_script_context.cc')
-rw-r--r-- | chromium/content/renderer/service_worker/service_worker_script_context.cc | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/chromium/content/renderer/service_worker/service_worker_script_context.cc b/chromium/content/renderer/service_worker/service_worker_script_context.cc new file mode 100644 index 00000000000..ad0534134ba --- /dev/null +++ b/chromium/content/renderer/service_worker/service_worker_script_context.cc @@ -0,0 +1,188 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#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" +#include "ipc/ipc_message.h" +#include "third_party/WebKit/public/platform/WebServiceWorkerRequest.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/web/WebServiceWorkerContextClient.h" +#include "third_party/WebKit/public/web/WebServiceWorkerContextProxy.h" + +namespace content { + +namespace { + +void SendPostMessageToDocumentOnMainThread( + ThreadSafeSender* sender, + int routing_id, + int client_id, + const base::string16& message, + scoped_ptr<blink::WebMessagePortChannelArray> channels) { + sender->Send(new ServiceWorkerHostMsg_PostMessageToDocument( + routing_id, client_id, message, + WebMessagePortChannelImpl::ExtractMessagePortIDs(channels.release()))); +} + +} // namespace + +ServiceWorkerScriptContext::ServiceWorkerScriptContext( + EmbeddedWorkerContextClient* embedded_context, + blink::WebServiceWorkerContextProxy* proxy) + : embedded_context_(embedded_context), + proxy_(proxy) { +} + +ServiceWorkerScriptContext::~ServiceWorkerScriptContext() {} + +void ServiceWorkerScriptContext::OnMessageReceived( + const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(ServiceWorkerScriptContext, message) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ActivateEvent, OnActivateEvent) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_FetchEvent, OnFetchEvent) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_InstallEvent, OnInstallEvent) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SyncEvent, OnSyncEvent) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_PushEvent, OnPushEvent) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToWorker, OnPostMessage) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetClientDocuments, + OnDidGetClientDocuments) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + DCHECK(handled); +} + +void ServiceWorkerScriptContext::DidHandleActivateEvent( + int request_id, + blink::WebServiceWorkerEventResult result) { + Send(new ServiceWorkerHostMsg_ActivateEventFinished( + GetRoutingID(), request_id, result)); +} + +void ServiceWorkerScriptContext::DidHandleInstallEvent( + int request_id, + blink::WebServiceWorkerEventResult result) { + Send(new ServiceWorkerHostMsg_InstallEventFinished( + GetRoutingID(), request_id, result)); +} + +void ServiceWorkerScriptContext::DidHandleFetchEvent( + int request_id, + ServiceWorkerFetchEventResult result, + const ServiceWorkerResponse& response) { + Send(new ServiceWorkerHostMsg_FetchEventFinished( + GetRoutingID(), request_id, result, response)); +} + +void ServiceWorkerScriptContext::DidHandleSyncEvent(int request_id) { + Send(new ServiceWorkerHostMsg_SyncEventFinished( + GetRoutingID(), request_id)); +} + +void ServiceWorkerScriptContext::GetClientDocuments( + blink::WebServiceWorkerClientsCallbacks* callbacks) { + DCHECK(callbacks); + int request_id = pending_clients_callbacks_.Add(callbacks); + Send(new ServiceWorkerHostMsg_GetClientDocuments( + GetRoutingID(), request_id)); +} + +void ServiceWorkerScriptContext::PostMessageToDocument( + int client_id, + const base::string16& message, + scoped_ptr<blink::WebMessagePortChannelArray> channels) { + // This may send channels 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, base::Passed(&channels))); +} + +void ServiceWorkerScriptContext::Send(IPC::Message* message) { + embedded_context_->Send(message); +} + +void ServiceWorkerScriptContext::OnActivateEvent(int request_id) { + proxy_->dispatchActivateEvent(request_id); +} + +void ServiceWorkerScriptContext::OnInstallEvent(int request_id, + int active_version_id) { + proxy_->dispatchInstallEvent(request_id); +} + +void ServiceWorkerScriptContext::OnFetchEvent( + int request_id, + const ServiceWorkerFetchRequest& request) { + blink::WebServiceWorkerRequest webRequest; + webRequest.setURL(blink::WebURL(request.url)); + webRequest.setMethod(blink::WebString::fromUTF8(request.method)); + for (std::map<std::string, std::string>::const_iterator it = + request.headers.begin(); + it != request.headers.end(); + ++it) { + webRequest.setHeader(blink::WebString::fromUTF8(it->first), + blink::WebString::fromUTF8(it->second)); + } + proxy_->dispatchFetchEvent(request_id, webRequest); +} + +void ServiceWorkerScriptContext::OnSyncEvent(int request_id) { + proxy_->dispatchSyncEvent(request_id); +} + +void ServiceWorkerScriptContext::OnPushEvent(int request_id, + const std::string& data) { + proxy_->dispatchPushEvent(request_id, blink::WebString::fromUTF8(data)); + Send(new ServiceWorkerHostMsg_PushEventFinished( + GetRoutingID(), request_id)); +} + +void ServiceWorkerScriptContext::OnPostMessage( + const base::string16& message, + const std::vector<int>& sent_message_port_ids, + const std::vector<int>& new_routing_ids) { + std::vector<WebMessagePortChannelImpl*> ports; + if (!sent_message_port_ids.empty()) { + base::MessageLoopProxy* loop_proxy = embedded_context_->main_thread_proxy(); + 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], loop_proxy); + } + } + + proxy_->dispatchMessageEvent(message, ports); +} + +void ServiceWorkerScriptContext::OnDidGetClientDocuments( + int request_id, const std::vector<int>& client_ids) { + blink::WebServiceWorkerClientsCallbacks* callbacks = + pending_clients_callbacks_.Lookup(request_id); + if (!callbacks) { + NOTREACHED() << "Got stray response: " << request_id; + return; + } + scoped_ptr<blink::WebServiceWorkerClientsInfo> info( + new blink::WebServiceWorkerClientsInfo); + info->clientIDs = client_ids; + callbacks->onSuccess(info.release()); + pending_clients_callbacks_.Remove(request_id); +} + +int ServiceWorkerScriptContext::GetRoutingID() const { + return embedded_context_->embedded_worker_id(); +} + +} // namespace content |