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#ifndef PPAPI_HOST_PPAPI_HOST_H_
6#define PPAPI_HOST_PPAPI_HOST_H_
7
8#include <map>
9#include <vector>
10
11#include "base/compiler_specific.h"
12#include "base/memory/linked_ptr.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/scoped_vector.h"
15#include "base/observer_list.h"
16#include "ipc/ipc_listener.h"
17#include "ipc/ipc_sender.h"
18#include "ppapi/c/pp_instance.h"
19#include "ppapi/c/pp_resource.h"
20#include "ppapi/host/ppapi_host_export.h"
21#include "ppapi/shared_impl/ppapi_permissions.h"
22
23namespace ppapi {
24
25namespace proxy {
26class ResourceMessageCallParams;
27class ResourceMessageReplyParams;
28class SerializedHandle;
29}
30
31namespace host {
32
33class HostFactory;
34struct HostMessageContext;
35class InstanceMessageFilter;
36struct ReplyMessageContext;
37class ResourceHost;
38
39// The host provides routing and tracking for resource message calls that
40// come from the plugin to the host (browser or renderer), and the
41// corresponding replies.
42class PPAPI_HOST_EXPORT PpapiHost : public IPC::Sender, public IPC::Listener {
43 public:
44  // The sender is the channel to the plugin for outgoing messages.
45  // Normally the creator will add filters for resource creation messages
46  // (AddHostFactoryFilter) and instance messages (AddInstanceMessageFilter)
47  // after construction.
48  PpapiHost(IPC::Sender* sender, const PpapiPermissions& perms);
49  virtual ~PpapiHost();
50
51  const PpapiPermissions& permissions() const { return permissions_; }
52
53  // Sender implementation. Forwards to the sender_.
54  virtual bool Send(IPC::Message* msg) OVERRIDE;
55
56  // Listener implementation.
57  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
58
59  // Sends the given reply message to the plugin.
60  void SendReply(const ReplyMessageContext& context,
61                 const IPC::Message& msg);
62
63  // Sends the given unsolicited reply message to the plugin.
64  void SendUnsolicitedReply(PP_Resource resource, const IPC::Message& msg);
65
66  // Similar to |SendUnsolicitedReply()|, but also sends handles.
67  void SendUnsolicitedReplyWithHandles(
68      PP_Resource resource,
69      const IPC::Message& msg,
70      const std::vector<proxy::SerializedHandle>& handles);
71
72  // Create a ResourceHost with the given |nested_msg|.
73  scoped_ptr<ResourceHost> CreateResourceHost(
74      const proxy::ResourceMessageCallParams& params,
75      PP_Instance instance,
76      const IPC::Message& nested_msg);
77
78  // Adds the given host resource as a pending one (with no corresponding
79  // PluginResource object and no PP_Resource ID yet). The pending resource ID
80  // is returned. See PpapiHostMsg_AttachToPendingHost.
81  int AddPendingResourceHost(scoped_ptr<ResourceHost> resource_host);
82
83  // Adds the given host factory filter to the host. The PpapiHost will take
84  // ownership of the pointer.
85  void AddHostFactoryFilter(scoped_ptr<HostFactory> filter);
86
87  // Adds the given message filter to the host. The PpapiHost will take
88  // ownership of the pointer.
89  void AddInstanceMessageFilter(scoped_ptr<InstanceMessageFilter> filter);
90
91  // Returns null if the resource doesn't exist.
92  host::ResourceHost* GetResourceHost(PP_Resource resource) const;
93
94 private:
95  friend class InstanceMessageFilter;
96
97  void HandleResourceCall(
98      const proxy::ResourceMessageCallParams& params,
99      const IPC::Message& nested_msg,
100      HostMessageContext* context);
101
102  // Message handlers.
103  void OnHostMsgResourceCall(const proxy::ResourceMessageCallParams& params,
104                             const IPC::Message& nested_msg);
105  void OnHostMsgInProcessResourceCall(
106      int routing_id,
107      const proxy::ResourceMessageCallParams& params,
108      const IPC::Message& nested_msg);
109  void OnHostMsgResourceSyncCall(
110      const proxy::ResourceMessageCallParams& params,
111      const IPC::Message& nested_msg,
112      IPC::Message* reply_msg);
113  void OnHostMsgResourceCreated(const proxy::ResourceMessageCallParams& param,
114                                PP_Instance instance,
115                                const IPC::Message& nested_msg);
116  void OnHostMsgAttachToPendingHost(PP_Resource resource, int pending_host_id);
117  void OnHostMsgResourceDestroyed(PP_Resource resource);
118
119  // Non-owning pointer.
120  IPC::Sender* sender_;
121
122  PpapiPermissions permissions_;
123
124  // Filters for resource creation messages. Note that since we don't support
125  // deleting these dynamically we don't need to worry about modifications
126  // during iteration. If we add that capability, this should be replaced with
127  // an ObserverList.
128  ScopedVector<HostFactory> host_factory_filters_;
129
130  // Filters for instance messages. Note that since we don't support deleting
131  // these dynamically we don't need to worry about modifications during
132  // iteration. If we add that capability, this should be replaced with an
133  // ObserverList.
134  ScopedVector<InstanceMessageFilter> instance_message_filters_;
135
136  typedef std::map<PP_Resource, linked_ptr<ResourceHost> > ResourceMap;
137  ResourceMap resources_;
138
139  // Resources that have been created in the host and have not yet had the
140  // corresponding PluginResource associated with them.
141  // See PpapiHostMsg_AttachToPendingHost.
142  typedef std::map<int, linked_ptr<ResourceHost> > PendingHostResourceMap;
143  PendingHostResourceMap pending_resource_hosts_;
144  int next_pending_resource_host_id_;
145
146  DISALLOW_COPY_AND_ASSIGN(PpapiHost);
147};
148
149}  // namespace host
150}  // namespace ppapi
151
152#endif  // PPAPI_HOST_PPAPIE_HOST_H_
153