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