1 // Copyright (c) 2011 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.
5 #include "content/renderer/websharedworker_proxy.h"
7 #include "content/child/webmessageportchannel_impl.h"
8 #include "content/common/message_router.h"
9 #include "content/common/view_messages.h"
10 #include "content/common/worker_messages.h"
11 #include "third_party/WebKit/public/platform/WebURL.h"
12 #include "third_party/WebKit/public/web/WebSharedWorkerClient.h"
16 WebSharedWorkerProxy::WebSharedWorkerProxy(MessageRouter
* router
,
17 unsigned long long document_id
,
19 int render_frame_route_id
)
20 : route_id_(route_id
),
21 render_frame_route_id_(render_frame_route_id
),
23 document_id_(document_id
),
24 pending_route_id_(route_id
),
25 connect_listener_(NULL
),
27 router_
->AddRoute(route_id_
, this);
30 WebSharedWorkerProxy::~WebSharedWorkerProxy() {
33 // Free up any unsent queued messages.
34 for (size_t i
= 0; i
< queued_messages_
.size(); ++i
)
35 delete queued_messages_
[i
];
38 void WebSharedWorkerProxy::Disconnect() {
39 if (route_id_
== MSG_ROUTING_NONE
)
42 // So the messages from WorkerContext (like WorkerContextDestroyed) do not
43 // come after nobody is listening. Since Worker and WorkerContext can
44 // terminate independently, already sent messages may still be in the pipe.
45 router_
->RemoveRoute(route_id_
);
47 route_id_
= MSG_ROUTING_NONE
;
50 bool WebSharedWorkerProxy::Send(IPC::Message
* message
) {
51 // It's possible that messages will be sent before the worker is created, in
52 // which case route_id_ will be none. Or the worker object can be interacted
53 // with before the browser process told us that it started, in which case we
54 // also want to queue the message.
56 queued_messages_
.push_back(message
);
60 // For now we proxy all messages to the worker process through the browser.
61 // Revisit if we find this slow.
62 // TODO(jabdelmalek): handle sync messages if we need them.
63 IPC::Message
* wrapped_msg
= new ViewHostMsg_ForwardToWorker(*message
);
65 return router_
->Send(wrapped_msg
);
68 void WebSharedWorkerProxy::SendQueuedMessages() {
69 DCHECK(queued_messages_
.size());
70 std::vector
<IPC::Message
*> queued_messages
= queued_messages_
;
71 queued_messages_
.clear();
72 for (size_t i
= 0; i
< queued_messages
.size(); ++i
) {
73 queued_messages
[i
]->set_routing_id(route_id_
);
74 Send(queued_messages
[i
]);
78 void WebSharedWorkerProxy::connect(blink::WebMessagePortChannel
* channel
,
79 ConnectListener
* listener
) {
80 WebMessagePortChannelImpl
* webchannel
=
81 static_cast<WebMessagePortChannelImpl
*>(channel
);
83 int message_port_id
= webchannel
->message_port_id();
84 DCHECK(message_port_id
!= MSG_ROUTING_NONE
);
85 webchannel
->QueueMessages();
87 Send(new WorkerMsg_Connect(route_id_
, message_port_id
, MSG_ROUTING_NONE
));
88 connect_listener_
= listener
;
91 bool WebSharedWorkerProxy::OnMessageReceived(const IPC::Message
& message
) {
93 IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerProxy
, message
)
94 IPC_MESSAGE_HANDLER(ViewMsg_WorkerCreated
, OnWorkerCreated
)
95 IPC_MESSAGE_HANDLER(ViewMsg_WorkerScriptLoadFailed
,
96 OnWorkerScriptLoadFailed
)
97 IPC_MESSAGE_HANDLER(ViewMsg_WorkerConnected
,
99 IPC_MESSAGE_UNHANDLED(handled
= false)
100 IPC_END_MESSAGE_MAP()
104 void WebSharedWorkerProxy::OnWorkerCreated() {
106 // The worker is created - now send off the WorkerMsg_Connect message and
107 // any other queued messages
108 SendQueuedMessages();
111 void WebSharedWorkerProxy::OnWorkerScriptLoadFailed() {
112 if (connect_listener_
) {
113 // This can result in this object being freed.
114 connect_listener_
->scriptLoadFailed();
118 void WebSharedWorkerProxy::OnWorkerConnected() {
119 if (connect_listener_
) {
120 // This can result in this object being freed.
121 connect_listener_
->connected();
125 } // namespace content