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_PROXY_RESOURCE_MESSAGE_PARAMS_H_ 6 #define PPAPI_PROXY_RESOURCE_MESSAGE_PARAMS_H_ 7 8 #include <vector> 9 10 #include "base/memory/ref_counted.h" 11 #include "ipc/ipc_message_utils.h" 12 #include "ppapi/c/pp_resource.h" 13 #include "ppapi/proxy/ppapi_proxy_export.h" 14 #include "ppapi/proxy/serialized_handle.h" 15 16 namespace ppapi { 17 namespace proxy { 18 19 // Common parameters for resource call and reply params structures below. 20 class PPAPI_PROXY_EXPORT ResourceMessageParams { 21 public: 22 virtual ~ResourceMessageParams(); 23 24 PP_Resource pp_resource() const { return pp_resource_; } 25 int32_t sequence() const { return sequence_; } 26 27 // Note that the caller doesn't take ownership of the returned handles. 28 const std::vector<SerializedHandle>& handles() const { 29 return handles_->data(); 30 } 31 32 // Makes ResourceMessageParams leave its handles open, even if they weren't 33 // taken using a Take.* function. After this call, no Take.* calls are 34 // allowed. 35 void ConsumeHandles() const; 36 37 // Returns the handle at the given index if it exists and is of the given 38 // type. The corresponding slot in the list is set to an invalid handle. 39 // If the index doesn't exist or the handle isn't of the given type, returns 40 // an invalid handle. 41 // Note that the caller is responsible for closing the returned handle, if it 42 // is valid. 43 SerializedHandle TakeHandleOfTypeAtIndex(size_t index, 44 SerializedHandle::Type type) const; 45 46 // Helper functions to return shared memory, socket or file handles passed in 47 // the params struct. 48 // If the index has a valid handle of the given type, it will be placed in the 49 // output parameter, the corresponding slot in the list will be set to an 50 // invalid handle, and the function will return true. If the handle doesn't 51 // exist or is a different type, the functions will return false and the 52 // output parameter will be untouched. 53 // 54 // Note: 1) the handle could still be a "null" or invalid handle of the right 55 // type and the functions will succeed. 56 // 2) the caller is responsible for closing the returned handle, if it 57 // is valid. 58 bool TakeSharedMemoryHandleAtIndex(size_t index, 59 base::SharedMemoryHandle* handle) const; 60 bool TakeSocketHandleAtIndex(size_t index, 61 IPC::PlatformFileForTransit* handle) const; 62 bool TakeFileHandleAtIndex(size_t index, 63 IPC::PlatformFileForTransit* handle) const; 64 void TakeAllSharedMemoryHandles( 65 std::vector<base::SharedMemoryHandle>* handles) const; 66 67 // Appends the given handle to the list of handles sent with the call or 68 // reply. 69 void AppendHandle(const SerializedHandle& handle) const; 70 71 protected: 72 ResourceMessageParams(); 73 ResourceMessageParams(PP_Resource resource, int32_t sequence); 74 75 virtual void Serialize(IPC::Message* msg) const; 76 virtual bool Deserialize(const IPC::Message* msg, PickleIterator* iter); 77 78 // Writes everything except the handles to |msg|. 79 void WriteHeader(IPC::Message* msg) const; 80 // Writes the handles to |msg|. 81 void WriteHandles(IPC::Message* msg) const; 82 // Matching deserialize helpers. 83 bool ReadHeader(const IPC::Message* msg, PickleIterator* iter); 84 bool ReadHandles(const IPC::Message* msg, PickleIterator* iter); 85 86 private: 87 class SerializedHandles 88 : public base::RefCountedThreadSafe<SerializedHandles> { 89 public: 90 SerializedHandles(); 91 ~SerializedHandles(); 92 93 void set_should_close(bool value) { should_close_ = value; } 94 std::vector<SerializedHandle>& data() { return data_; } 95 96 private: 97 friend class base::RefCountedThreadSafe<SerializedHandles>; 98 99 // Whether the handles stored in |data_| should be closed when this object 100 // goes away. 101 // 102 // It is set to true by ResourceMessageParams::Deserialize(), so that the 103 // receiving side of the params (the host side for 104 // ResourceMessageCallParams; the plugin side for 105 // ResourceMessageReplyParams) will close those handles which haven't been 106 // taken using any of the Take*() methods. 107 bool should_close_; 108 std::vector<SerializedHandle> data_; 109 }; 110 111 PP_Resource pp_resource_; 112 113 // Identifier for this message. Sequence numbers are quasi-unique within a 114 // resource, but will overlap between different resource objects. 115 // 116 // If you send a lot of messages, the ID may wrap around. This is OK. All IDs 117 // are valid and 0 and -1 aren't special, so those cases won't confuse us. 118 // In practice, if you send more than 4 billion messages for a resource, the 119 // old ones will be long gone and there will be no collisions. 120 // 121 // If there is a malicious plugin (or exceptionally bad luck) that causes a 122 // wraparound and collision the worst that will happen is that we can get 123 // confused between different callbacks. But since these can only cause 124 // confusion within the plugin and within callbacks on the same resource, 125 // there shouldn't be a security problem. 126 int32_t sequence_; 127 128 // A list of all handles transferred in the message. Handles go here so that 129 // the NaCl adapter can extract them generally when it rewrites them to 130 // go between Windows and NaCl (Posix) apps. 131 // TODO(yzshen): Mark it as mutable so that we can take/append handles using a 132 // const reference. We need to change all the callers and make it not mutable. 133 mutable scoped_refptr<SerializedHandles> handles_; 134 }; 135 136 // Parameters common to all ResourceMessage "Call" requests. 137 class PPAPI_PROXY_EXPORT ResourceMessageCallParams 138 : public ResourceMessageParams { 139 public: 140 ResourceMessageCallParams(); 141 ResourceMessageCallParams(PP_Resource resource, int32_t sequence); 142 virtual ~ResourceMessageCallParams(); 143 144 void set_has_callback() { has_callback_ = true; } 145 bool has_callback() const { return has_callback_; } 146 147 virtual void Serialize(IPC::Message* msg) const OVERRIDE; 148 virtual bool Deserialize(const IPC::Message* msg, 149 PickleIterator* iter) OVERRIDE; 150 151 private: 152 bool has_callback_; 153 }; 154 155 // Parameters common to all ResourceMessage "Reply" requests. 156 class PPAPI_PROXY_EXPORT ResourceMessageReplyParams 157 : public ResourceMessageParams { 158 public: 159 ResourceMessageReplyParams(); 160 ResourceMessageReplyParams(PP_Resource resource, int32_t sequence); 161 virtual ~ResourceMessageReplyParams(); 162 163 void set_result(int32_t r) { result_ = r; } 164 int32_t result() const { return result_; } 165 166 virtual void Serialize(IPC::Message* msg) const OVERRIDE; 167 virtual bool Deserialize(const IPC::Message* msg, 168 PickleIterator* iter) OVERRIDE; 169 170 // Writes everything except the handles to |msg|. 171 void WriteReplyHeader(IPC::Message* msg) const; 172 173 private: 174 // Pepper "result code" for the callback. 175 int32_t result_; 176 }; 177 178 } // namespace proxy 179 } // namespace ppapi 180 181 namespace IPC { 182 183 template <> struct PPAPI_PROXY_EXPORT 184 ParamTraits<ppapi::proxy::ResourceMessageCallParams> { 185 typedef ppapi::proxy::ResourceMessageCallParams param_type; 186 static void Write(Message* m, const param_type& p) { 187 p.Serialize(m); 188 } 189 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { 190 return r->Deserialize(m, iter); 191 } 192 static void Log(const param_type& p, std::string* l) { 193 } 194 }; 195 196 template <> struct PPAPI_PROXY_EXPORT 197 ParamTraits<ppapi::proxy::ResourceMessageReplyParams> { 198 typedef ppapi::proxy::ResourceMessageReplyParams param_type; 199 static void Write(Message* m, const param_type& p) { 200 p.Serialize(m); 201 } 202 static bool Read(const Message* m, PickleIterator* iter, param_type* r) { 203 return r->Deserialize(m, iter); 204 } 205 static void Log(const param_type& p, std::string* l) { 206 } 207 }; 208 209 } // namespace IPC 210 211 #endif // PPAPI_PROXY_RESOURCE_MESSAGE_PARAMS_H_ 212