• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/renderer/service_worker/service_worker_script_context.h"
6 
7 #include "base/logging.h"
8 #include "content/child/thread_safe_sender.h"
9 #include "content/child/webmessageportchannel_impl.h"
10 #include "content/common/service_worker/service_worker_messages.h"
11 #include "content/renderer/service_worker/embedded_worker_context_client.h"
12 #include "ipc/ipc_message.h"
13 #include "third_party/WebKit/public/platform/WebServiceWorkerRequest.h"
14 #include "third_party/WebKit/public/platform/WebString.h"
15 #include "third_party/WebKit/public/platform/WebURL.h"
16 #include "third_party/WebKit/public/web/WebServiceWorkerContextClient.h"
17 #include "third_party/WebKit/public/web/WebServiceWorkerContextProxy.h"
18 
19 namespace content {
20 
21 namespace {
22 
SendPostMessageToDocumentOnMainThread(ThreadSafeSender * sender,int routing_id,int client_id,const base::string16 & message,scoped_ptr<blink::WebMessagePortChannelArray> channels)23 void SendPostMessageToDocumentOnMainThread(
24     ThreadSafeSender* sender,
25     int routing_id,
26     int client_id,
27     const base::string16& message,
28     scoped_ptr<blink::WebMessagePortChannelArray> channels) {
29   sender->Send(new ServiceWorkerHostMsg_PostMessageToDocument(
30       routing_id, client_id, message,
31       WebMessagePortChannelImpl::ExtractMessagePortIDs(channels.release())));
32 }
33 
34 }  // namespace
35 
ServiceWorkerScriptContext(EmbeddedWorkerContextClient * embedded_context,blink::WebServiceWorkerContextProxy * proxy)36 ServiceWorkerScriptContext::ServiceWorkerScriptContext(
37     EmbeddedWorkerContextClient* embedded_context,
38     blink::WebServiceWorkerContextProxy* proxy)
39     : embedded_context_(embedded_context),
40       proxy_(proxy) {
41 }
42 
~ServiceWorkerScriptContext()43 ServiceWorkerScriptContext::~ServiceWorkerScriptContext() {}
44 
OnMessageReceived(const IPC::Message & message)45 void ServiceWorkerScriptContext::OnMessageReceived(
46     const IPC::Message& message) {
47   bool handled = true;
48   IPC_BEGIN_MESSAGE_MAP(ServiceWorkerScriptContext, message)
49     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ActivateEvent, OnActivateEvent)
50     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_FetchEvent, OnFetchEvent)
51     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_InstallEvent, OnInstallEvent)
52     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SyncEvent, OnSyncEvent)
53     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_PushEvent, OnPushEvent)
54     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToWorker, OnPostMessage)
55     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetClientDocuments,
56                         OnDidGetClientDocuments)
57     IPC_MESSAGE_UNHANDLED(handled = false)
58   IPC_END_MESSAGE_MAP()
59   DCHECK(handled);
60 }
61 
DidHandleActivateEvent(int request_id,blink::WebServiceWorkerEventResult result)62 void ServiceWorkerScriptContext::DidHandleActivateEvent(
63     int request_id,
64     blink::WebServiceWorkerEventResult result) {
65   Send(new ServiceWorkerHostMsg_ActivateEventFinished(
66       GetRoutingID(), request_id, result));
67 }
68 
DidHandleInstallEvent(int request_id,blink::WebServiceWorkerEventResult result)69 void ServiceWorkerScriptContext::DidHandleInstallEvent(
70     int request_id,
71     blink::WebServiceWorkerEventResult result) {
72   Send(new ServiceWorkerHostMsg_InstallEventFinished(
73       GetRoutingID(), request_id, result));
74 }
75 
DidHandleFetchEvent(int request_id,ServiceWorkerFetchEventResult result,const ServiceWorkerResponse & response)76 void ServiceWorkerScriptContext::DidHandleFetchEvent(
77     int request_id,
78     ServiceWorkerFetchEventResult result,
79     const ServiceWorkerResponse& response) {
80   Send(new ServiceWorkerHostMsg_FetchEventFinished(
81       GetRoutingID(), request_id, result, response));
82 }
83 
DidHandleSyncEvent(int request_id)84 void ServiceWorkerScriptContext::DidHandleSyncEvent(int request_id) {
85   Send(new ServiceWorkerHostMsg_SyncEventFinished(
86       GetRoutingID(), request_id));
87 }
88 
GetClientDocuments(blink::WebServiceWorkerClientsCallbacks * callbacks)89 void ServiceWorkerScriptContext::GetClientDocuments(
90     blink::WebServiceWorkerClientsCallbacks* callbacks) {
91   DCHECK(callbacks);
92   int request_id = pending_clients_callbacks_.Add(callbacks);
93   Send(new ServiceWorkerHostMsg_GetClientDocuments(
94       GetRoutingID(), request_id));
95 }
96 
PostMessageToDocument(int client_id,const base::string16 & message,scoped_ptr<blink::WebMessagePortChannelArray> channels)97 void ServiceWorkerScriptContext::PostMessageToDocument(
98     int client_id,
99     const base::string16& message,
100     scoped_ptr<blink::WebMessagePortChannelArray> channels) {
101   // This may send channels for MessagePorts, and all internal book-keeping
102   // messages for MessagePort (e.g. QueueMessages) are sent from main thread
103   // (with thread hopping), so we need to do the same thread hopping here not
104   // to overtake those messages.
105   embedded_context_->main_thread_proxy()->PostTask(
106       FROM_HERE,
107       base::Bind(&SendPostMessageToDocumentOnMainThread,
108                  make_scoped_refptr(embedded_context_->thread_safe_sender()),
109                  GetRoutingID(), client_id, message, base::Passed(&channels)));
110 }
111 
Send(IPC::Message * message)112 void ServiceWorkerScriptContext::Send(IPC::Message* message) {
113   embedded_context_->Send(message);
114 }
115 
OnActivateEvent(int request_id)116 void ServiceWorkerScriptContext::OnActivateEvent(int request_id) {
117   proxy_->dispatchActivateEvent(request_id);
118 }
119 
OnInstallEvent(int request_id,int active_version_id)120 void ServiceWorkerScriptContext::OnInstallEvent(int request_id,
121                                                 int active_version_id) {
122   proxy_->dispatchInstallEvent(request_id);
123 }
124 
OnFetchEvent(int request_id,const ServiceWorkerFetchRequest & request)125 void ServiceWorkerScriptContext::OnFetchEvent(
126     int request_id,
127     const ServiceWorkerFetchRequest& request) {
128   blink::WebServiceWorkerRequest webRequest;
129   webRequest.setURL(blink::WebURL(request.url));
130   webRequest.setMethod(blink::WebString::fromUTF8(request.method));
131   for (std::map<std::string, std::string>::const_iterator it =
132            request.headers.begin();
133        it != request.headers.end();
134        ++it) {
135     webRequest.setHeader(blink::WebString::fromUTF8(it->first),
136                          blink::WebString::fromUTF8(it->second));
137   }
138   proxy_->dispatchFetchEvent(request_id, webRequest);
139 }
140 
OnSyncEvent(int request_id)141 void ServiceWorkerScriptContext::OnSyncEvent(int request_id) {
142   proxy_->dispatchSyncEvent(request_id);
143 }
144 
OnPushEvent(int request_id,const std::string & data)145 void ServiceWorkerScriptContext::OnPushEvent(int request_id,
146                                              const std::string& data) {
147   proxy_->dispatchPushEvent(request_id, blink::WebString::fromUTF8(data));
148   Send(new ServiceWorkerHostMsg_PushEventFinished(
149       GetRoutingID(), request_id));
150 }
151 
OnPostMessage(const base::string16 & message,const std::vector<int> & sent_message_port_ids,const std::vector<int> & new_routing_ids)152 void ServiceWorkerScriptContext::OnPostMessage(
153     const base::string16& message,
154     const std::vector<int>& sent_message_port_ids,
155     const std::vector<int>& new_routing_ids) {
156   std::vector<WebMessagePortChannelImpl*> ports;
157   if (!sent_message_port_ids.empty()) {
158     base::MessageLoopProxy* loop_proxy = embedded_context_->main_thread_proxy();
159     ports.resize(sent_message_port_ids.size());
160     for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
161       ports[i] = new WebMessagePortChannelImpl(
162           new_routing_ids[i], sent_message_port_ids[i], loop_proxy);
163     }
164   }
165 
166   proxy_->dispatchMessageEvent(message, ports);
167 }
168 
OnDidGetClientDocuments(int request_id,const std::vector<int> & client_ids)169 void ServiceWorkerScriptContext::OnDidGetClientDocuments(
170     int request_id, const std::vector<int>& client_ids) {
171   blink::WebServiceWorkerClientsCallbacks* callbacks =
172       pending_clients_callbacks_.Lookup(request_id);
173   if (!callbacks) {
174     NOTREACHED() << "Got stray response: " << request_id;
175     return;
176   }
177   scoped_ptr<blink::WebServiceWorkerClientsInfo> info(
178       new blink::WebServiceWorkerClientsInfo);
179   info->clientIDs = client_ids;
180   callbacks->onSuccess(info.release());
181   pending_clients_callbacks_.Remove(request_id);
182 }
183 
GetRoutingID() const184 int ServiceWorkerScriptContext::GetRoutingID() const {
185   return embedded_context_->embedded_worker_id();
186 }
187 
188 }  // namespace content
189