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.
4
5#include "base/callback.h"
6#include "base/basictypes.h"
7#include "base/memory/scoped_ptr.h"
8#include "base/memory/weak_ptr.h"
9#include "ppapi/c/pp_instance.h"
10#include "ppapi/proxy/connection.h"
11#include "ppapi/proxy/resource_message_params.h"
12
13namespace IPC {
14class Message;
15class MessageReplyDeserializer;
16}  // namespace
17
18namespace content {
19
20class RendererPpapiHostImpl;
21
22// This class fakes an IPC channel so that we can take the new resources with
23// IPC backends and run them in-process.
24//
25// (See pepper_in_process_resource_creation.h for more background.)
26//
27// This class just provides the fake routing for in-process plugins.
28// Asynchronous messages are converted into an asynchronous execution of the
29// message receiver on the opposite end. Synchronous messages just call right
30// through.
31//
32// The resources in ppapi/proxy assume that there is an IPC connection to
33// both the renderer and the browser processes. They take a connection object
34// that includes both of these channels. However, in-process plugins don't
35// have a BrowserPpapiHost on the browser side to receive these messages.
36//
37// As a result, we can't support resources that rely on sending messages to the
38// browser process. Since this class is a stopgap until all interfaces are
39// converted and all plugins are run out-of-procss, we just choose not to
40// support faking IPC channels for resources that send messages directly to the
41// browser process. These resources will just have to use the "old" in-process
42// implementation until the conversion is complete and all this code can be
43// deleted.
44//
45// To keep things consistent, we provide an IPC::Sender for the browser channel
46// in the connection object supplied to resources. This dummy browser channel
47// will just assert and delete the message if anything is ever sent over it.
48//
49// There are two restrictions for in-process resource calls:
50// Sync messages can only be sent from the plugin to the host.
51// The host must handle sync messages synchronously.
52class PepperInProcessRouter {
53 public:
54  // The given host parameter owns this class and must outlive us.
55  PepperInProcessRouter(RendererPpapiHostImpl* host_impl);
56  ~PepperInProcessRouter();
57
58  // Returns the dummy sender for the cooresponding end of the in-process
59  // emulated channel.
60  IPC::Sender* GetPluginToRendererSender();
61  IPC::Sender* GetRendererToPluginSender();
62
63  // Returns a connection pair for use by a resource proxy. This includes
64  // the plugin->renderer sender as well as a dummy sender to the browser
65  // process. See the class comment above about the dummy sender.
66  ppapi::proxy::Connection GetPluginConnection(PP_Instance instance);
67
68  // Handles resource reply messages from the host.
69  static bool OnPluginMsgReceived(const IPC::Message& msg);
70
71 private:
72  bool SendToHost(IPC::Message* msg);
73  bool SendToPlugin(IPC::Message* msg);
74  void DispatchHostMsg(IPC::Message* msg);
75  void DispatchPluginMsg(IPC::Message* msg);
76  bool SendToBrowser(IPC::Message* msg);
77
78  RendererPpapiHostImpl* host_impl_;
79
80  class Channel;
81  scoped_ptr<Channel> browser_channel_;
82
83  // Renderer -> plugin channel.
84  scoped_ptr<Channel> host_to_plugin_router_;
85
86  // Plugin -> renderer channel.
87  scoped_ptr<Channel> plugin_to_host_router_;
88
89  // Pending sync message id.
90  int pending_message_id_;
91
92  // Reply deserializer of the pending sync message.
93  scoped_ptr<IPC::MessageReplyDeserializer> reply_deserializer_;
94
95  // Reply result of the pending sync message.
96  bool reply_result_;
97
98  base::WeakPtrFactory<PepperInProcessRouter> weak_factory_;
99
100  DISALLOW_COPY_AND_ASSIGN(PepperInProcessRouter);
101};
102
103}  // namespace content
104