Home | History | Annotate | Download | only in proxy
      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