1 // Copyright (c) 2012 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/pepper/pepper_in_process_router.h"
8 #include "base/message_loop.h"
9 #include "content/renderer/pepper/renderer_ppapi_host_impl.h"
10 #include "ipc/ipc_message.h"
11 #include "ipc/ipc_sender.h"
12 #include "ppapi/proxy/ppapi_messages.h"
13 #include "ppapi/shared_impl/ppapi_globals.h"
14 #include "ppapi/shared_impl/resource_tracker.h"
18 class PepperInProcessRouter::Channel
: public IPC::Sender
{
20 Channel(const base::Callback
<bool(IPC::Message
*)>& callback
)
21 : callback_(callback
) {}
25 virtual bool Send(IPC::Message
* message
) OVERRIDE
{
26 return callback_
.Run(message
);
30 base::Callback
<bool(IPC::Message
*)> callback_
;
33 PepperInProcessRouter::PepperInProcessRouter(
34 RendererPpapiHostImpl
* host_impl
)
35 : host_impl_(host_impl
),
36 pending_message_id_(0),
39 dummy_browser_channel_
.reset(
40 new Channel(base::Bind(&PepperInProcessRouter::DummySendTo
,
41 base::Unretained(this))));
42 host_to_plugin_router_
.reset(
43 new Channel(base::Bind(&PepperInProcessRouter::SendToPlugin
,
44 base::Unretained(this))));
45 plugin_to_host_router_
.reset(
46 new Channel(base::Bind(&PepperInProcessRouter::SendToHost
,
47 base::Unretained(this))));
50 PepperInProcessRouter::~PepperInProcessRouter() {
53 IPC::Sender
* PepperInProcessRouter::GetPluginToRendererSender() {
54 return plugin_to_host_router_
.get();
57 IPC::Sender
* PepperInProcessRouter::GetRendererToPluginSender() {
58 return host_to_plugin_router_
.get();
61 ppapi::proxy::Connection
PepperInProcessRouter::GetPluginConnection() {
62 return ppapi::proxy::Connection(dummy_browser_channel_
.get(),
63 plugin_to_host_router_
.get());
66 bool PepperInProcessRouter::SendToHost(IPC::Message
* msg
) {
67 scoped_ptr
<IPC::Message
> message(msg
);
69 if (!message
->is_sync()) {
70 bool result
= host_impl_
->GetPpapiHost()->OnMessageReceived(*message
);
71 DCHECK(result
) << "The message was not handled by the host.";
75 pending_message_id_
= IPC::SyncMessage::GetMessageId(*message
);
76 reply_deserializer_
.reset(
77 static_cast<IPC::SyncMessage
*>(message
.get())->GetReplyDeserializer());
78 reply_result_
= false;
80 bool result
= host_impl_
->GetPpapiHost()->OnMessageReceived(*message
);
81 DCHECK(result
) << "The message was not handled by the host.";
83 pending_message_id_
= 0;
84 reply_deserializer_
.reset(NULL
);
88 bool PepperInProcessRouter::SendToPlugin(IPC::Message
* msg
) {
89 scoped_ptr
<IPC::Message
> message(msg
);
90 CHECK(!msg
->is_sync());
91 if (IPC::SyncMessage::IsMessageReplyTo(*message
, pending_message_id_
)) {
92 if (!msg
->is_reply_error())
93 reply_result_
= reply_deserializer_
->SerializeOutputParameters(*message
);
95 CHECK(!pending_message_id_
);
96 // Dispatch plugin messages from the message loop.
97 MessageLoop::current()->PostTask(
99 base::Bind(&PepperInProcessRouter::DispatchPluginMsg
,
100 weak_factory_
.GetWeakPtr(),
101 base::Owned(message
.release())));
106 void PepperInProcessRouter::DispatchPluginMsg(IPC::Message
* msg
) {
107 // Emulate the proxy by dispatching the relevant message here.
109 IPC_BEGIN_MESSAGE_MAP(PepperInProcessRouter
, *msg
)
110 IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply
, OnResourceReply
)
111 IPC_MESSAGE_UNHANDLED(handled
= false)
112 IPC_END_MESSAGE_MAP()
113 DCHECK(handled
) << "The message wasn't handled by the plugin.";
116 bool PepperInProcessRouter::DummySendTo(IPC::Message
*msg
) {
122 void PepperInProcessRouter::OnResourceReply(
123 const ppapi::proxy::ResourceMessageReplyParams
& reply_params
,
124 const IPC::Message
& nested_msg
) {
125 ppapi::Resource
* resource
=
126 ppapi::PpapiGlobals::Get()->GetResourceTracker()->GetResource(
127 reply_params
.pp_resource());
129 // The resource could have been destroyed while the async processing was
130 // pending. Just drop the message.
133 resource
->OnReplyReceived(reply_params
, nested_msg
);
136 } // namespace content