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 14 ResourceMessageParams::SerializedHandles::SerializedHandles() 15 : should_close_(false) { 16 } 17 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 27 ResourceMessageParams::ResourceMessageParams() 28 : pp_resource_(0), 29 sequence_(0), 30 handles_(new SerializedHandles()) { 31 } 32 33 ResourceMessageParams::ResourceMessageParams(PP_Resource resource, 34 int32_t sequence) 35 : pp_resource_(resource), 36 sequence_(sequence), 37 handles_(new SerializedHandles()) { 38 } 39 40 ResourceMessageParams::~ResourceMessageParams() { 41 } 42 43 void ResourceMessageParams::Serialize(IPC::Message* msg) const { 44 WriteHeader(msg); 45 WriteHandles(msg); 46 } 47 48 bool ResourceMessageParams::Deserialize(const IPC::Message* msg, 49 PickleIterator* iter) { 50 return ReadHeader(msg, iter) && ReadHandles(msg, iter); 51 } 52 53 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 58 void ResourceMessageParams::WriteHandles(IPC::Message* msg) const { 59 IPC::ParamTraits<std::vector<SerializedHandle> >::Write(msg, 60 handles_->data()); 61 } 62 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 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 77 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 84 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 96 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 107 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 118 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 129 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 138 void ResourceMessageParams::AppendHandle(const SerializedHandle& handle) const { 139 handles_->data().push_back(handle); 140 } 141 142 ResourceMessageCallParams::ResourceMessageCallParams() 143 : ResourceMessageParams(), 144 has_callback_(0) { 145 } 146 147 ResourceMessageCallParams::ResourceMessageCallParams(PP_Resource resource, 148 int32_t sequence) 149 : ResourceMessageParams(resource, sequence), 150 has_callback_(0) { 151 } 152 153 ResourceMessageCallParams::~ResourceMessageCallParams() { 154 } 155 156 void ResourceMessageCallParams::Serialize(IPC::Message* msg) const { 157 ResourceMessageParams::Serialize(msg); 158 IPC::ParamTraits<bool>::Write(msg, has_callback_); 159 } 160 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 168 ResourceMessageReplyParams::ResourceMessageReplyParams() 169 : ResourceMessageParams(), 170 result_(PP_OK) { 171 } 172 173 ResourceMessageReplyParams::ResourceMessageReplyParams(PP_Resource resource, 174 int32_t sequence) 175 : ResourceMessageParams(resource, sequence), 176 result_(PP_OK) { 177 } 178 179 ResourceMessageReplyParams::~ResourceMessageReplyParams() { 180 } 181 182 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 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 198 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