• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ppapi/proxy/resource_message_params.h"
6 
7 #include "base/logging.h"
8 #include "ppapi/c/pp_errors.h"
9 #include "ppapi/proxy/ppapi_messages.h"
10 
11 namespace ppapi {
12 namespace proxy {
13 
SerializedHandles()14 ResourceMessageParams::SerializedHandles::SerializedHandles()
15     : should_close_(false) {
16 }
17 
~SerializedHandles()18 ResourceMessageParams::SerializedHandles::~SerializedHandles() {
19   if (should_close_) {
20     for (std::vector<SerializedHandle>::iterator iter = data_.begin();
21          iter != data_.end(); ++iter) {
22       iter->Close();
23     }
24   }
25 }
26 
ResourceMessageParams()27 ResourceMessageParams::ResourceMessageParams()
28     : pp_resource_(0),
29       sequence_(0),
30       handles_(new SerializedHandles()) {
31 }
32 
ResourceMessageParams(PP_Resource resource,int32_t sequence)33 ResourceMessageParams::ResourceMessageParams(PP_Resource resource,
34                                              int32_t sequence)
35     : pp_resource_(resource),
36       sequence_(sequence),
37       handles_(new SerializedHandles()) {
38 }
39 
~ResourceMessageParams()40 ResourceMessageParams::~ResourceMessageParams() {
41 }
42 
Serialize(IPC::Message * msg) const43 void ResourceMessageParams::Serialize(IPC::Message* msg) const {
44   WriteHeader(msg);
45   WriteHandles(msg);
46 }
47 
Deserialize(const IPC::Message * msg,PickleIterator * iter)48 bool ResourceMessageParams::Deserialize(const IPC::Message* msg,
49                                         PickleIterator* iter) {
50   return ReadHeader(msg, iter) && ReadHandles(msg, iter);
51 }
52 
WriteHeader(IPC::Message * msg) const53 void ResourceMessageParams::WriteHeader(IPC::Message* msg) const {
54   IPC::ParamTraits<PP_Resource>::Write(msg, pp_resource_);
55   IPC::ParamTraits<int32_t>::Write(msg, sequence_);
56 }
57 
WriteHandles(IPC::Message * msg) const58 void ResourceMessageParams::WriteHandles(IPC::Message* msg) const {
59   IPC::ParamTraits<std::vector<SerializedHandle> >::Write(msg,
60                                                           handles_->data());
61 }
62 
ReadHeader(const IPC::Message * msg,PickleIterator * iter)63 bool ResourceMessageParams::ReadHeader(const IPC::Message* msg,
64                                        PickleIterator* iter) {
65   DCHECK(handles_->data().empty());
66   handles_->set_should_close(true);
67   return IPC::ParamTraits<PP_Resource>::Read(msg, iter, &pp_resource_) &&
68          IPC::ParamTraits<int32_t>::Read(msg, iter, &sequence_);
69 }
70 
ReadHandles(const IPC::Message * msg,PickleIterator * iter)71 bool ResourceMessageParams::ReadHandles(const IPC::Message* msg,
72                                         PickleIterator* iter) {
73   return IPC::ParamTraits<std::vector<SerializedHandle> >::Read(
74              msg, iter, &handles_->data());
75 }
76 
ConsumeHandles() const77 void ResourceMessageParams::ConsumeHandles() const {
78   // Note: we must not invalidate the handles. This is used for converting
79   // handles from the host OS to NaCl, and that conversion will not work if we
80   // invalidate the handles (see HandleConverter).
81   handles_->set_should_close(false);
82 }
83 
TakeHandleOfTypeAtIndex(size_t index,SerializedHandle::Type type) const84 SerializedHandle ResourceMessageParams::TakeHandleOfTypeAtIndex(
85     size_t index,
86     SerializedHandle::Type type) const {
87   SerializedHandle handle;
88   std::vector<SerializedHandle>& data = handles_->data();
89   if (index < data.size() && data[index].type() == type) {
90     handle = data[index];
91     data[index] = SerializedHandle();
92   }
93   return handle;
94 }
95 
TakeSharedMemoryHandleAtIndex(size_t index,base::SharedMemoryHandle * handle) const96 bool ResourceMessageParams::TakeSharedMemoryHandleAtIndex(
97     size_t index,
98     base::SharedMemoryHandle* handle) const {
99   SerializedHandle serialized = TakeHandleOfTypeAtIndex(
100       index, SerializedHandle::SHARED_MEMORY);
101   if (!serialized.is_shmem())
102     return false;
103   *handle = serialized.shmem();
104   return true;
105 }
106 
TakeSocketHandleAtIndex(size_t index,IPC::PlatformFileForTransit * handle) const107 bool ResourceMessageParams::TakeSocketHandleAtIndex(
108     size_t index,
109     IPC::PlatformFileForTransit* handle) const {
110   SerializedHandle serialized = TakeHandleOfTypeAtIndex(
111       index, SerializedHandle::SOCKET);
112   if (!serialized.is_socket())
113     return false;
114   *handle = serialized.descriptor();
115   return true;
116 }
117 
TakeFileHandleAtIndex(size_t index,IPC::PlatformFileForTransit * handle) const118 bool ResourceMessageParams::TakeFileHandleAtIndex(
119     size_t index,
120     IPC::PlatformFileForTransit* handle) const {
121   SerializedHandle serialized = TakeHandleOfTypeAtIndex(
122       index, SerializedHandle::FILE);
123   if (!serialized.is_file())
124     return false;
125   *handle = serialized.descriptor();
126   return true;
127 }
128 
TakeAllSharedMemoryHandles(std::vector<base::SharedMemoryHandle> * handles) const129 void ResourceMessageParams::TakeAllSharedMemoryHandles(
130     std::vector<base::SharedMemoryHandle>* handles) const {
131   for (size_t i = 0; i < handles_->data().size(); ++i) {
132     base::SharedMemoryHandle handle;
133     if (TakeSharedMemoryHandleAtIndex(i, &handle))
134       handles->push_back(handle);
135   }
136 }
137 
AppendHandle(const SerializedHandle & handle) const138 void ResourceMessageParams::AppendHandle(const SerializedHandle& handle) const {
139   handles_->data().push_back(handle);
140 }
141 
ResourceMessageCallParams()142 ResourceMessageCallParams::ResourceMessageCallParams()
143     : ResourceMessageParams(),
144       has_callback_(0) {
145 }
146 
ResourceMessageCallParams(PP_Resource resource,int32_t sequence)147 ResourceMessageCallParams::ResourceMessageCallParams(PP_Resource resource,
148                                                      int32_t sequence)
149     : ResourceMessageParams(resource, sequence),
150       has_callback_(0) {
151 }
152 
~ResourceMessageCallParams()153 ResourceMessageCallParams::~ResourceMessageCallParams() {
154 }
155 
Serialize(IPC::Message * msg) const156 void ResourceMessageCallParams::Serialize(IPC::Message* msg) const {
157   ResourceMessageParams::Serialize(msg);
158   IPC::ParamTraits<bool>::Write(msg, has_callback_);
159 }
160 
Deserialize(const IPC::Message * msg,PickleIterator * iter)161 bool ResourceMessageCallParams::Deserialize(const IPC::Message* msg,
162                                             PickleIterator* iter) {
163   if (!ResourceMessageParams::Deserialize(msg, iter))
164     return false;
165   return IPC::ParamTraits<bool>::Read(msg, iter, &has_callback_);
166 }
167 
ResourceMessageReplyParams()168 ResourceMessageReplyParams::ResourceMessageReplyParams()
169     : ResourceMessageParams(),
170       result_(PP_OK) {
171 }
172 
ResourceMessageReplyParams(PP_Resource resource,int32_t sequence)173 ResourceMessageReplyParams::ResourceMessageReplyParams(PP_Resource resource,
174                                                        int32_t sequence)
175     : ResourceMessageParams(resource, sequence),
176       result_(PP_OK) {
177 }
178 
~ResourceMessageReplyParams()179 ResourceMessageReplyParams::~ResourceMessageReplyParams() {
180 }
181 
Serialize(IPC::Message * msg) const182 void ResourceMessageReplyParams::Serialize(IPC::Message* msg) const {
183   // Rather than serialize all of ResourceMessageParams first, we serialize all
184   // non-handle data first, then the handles. When transferring to NaCl on
185   // Windows, we need to be able to translate Windows-style handles to POSIX-
186   // style handles, and it's easier to put all the regular stuff at the front.
187   WriteReplyHeader(msg);
188   WriteHandles(msg);
189 }
190 
Deserialize(const IPC::Message * msg,PickleIterator * iter)191 bool ResourceMessageReplyParams::Deserialize(const IPC::Message* msg,
192                                              PickleIterator* iter) {
193   return (ReadHeader(msg, iter) &&
194           IPC::ParamTraits<int32_t>::Read(msg, iter, &result_) &&
195           ReadHandles(msg, iter));
196 }
197 
WriteReplyHeader(IPC::Message * msg) const198 void ResourceMessageReplyParams::WriteReplyHeader(IPC::Message* msg) const {
199   WriteHeader(msg);
200   IPC::ParamTraits<int32_t>::Write(msg, result_);
201 }
202 
203 }  // namespace proxy
204 }  // namespace ppapi
205