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