// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PPAPI_PROXY_RESOURCE_MESSAGE_PARAMS_H_
#define PPAPI_PROXY_RESOURCE_MESSAGE_PARAMS_H_

#include <vector>

#include "base/memory/ref_counted.h"
#include "ipc/ipc_message_utils.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/proxy/serialized_handle.h"

namespace ppapi {
namespace proxy {

// Common parameters for resource call and reply params structures below.
class PPAPI_PROXY_EXPORT ResourceMessageParams {
 public:
  virtual ~ResourceMessageParams();

  PP_Resource pp_resource() const { return pp_resource_; }
  int32_t sequence() const { return sequence_; }

  // Note that the caller doesn't take ownership of the returned handles.
  const std::vector<SerializedHandle>& handles() const {
    return handles_->data();
  }

  // Makes ResourceMessageParams leave its handles open, even if they weren't
  // taken using a Take.* function. After this call, no Take.* calls are
  // allowed.
  void ConsumeHandles() const;

  // Returns the handle at the given index if it exists and is of the given
  // type. The corresponding slot in the list is set to an invalid handle.
  // If the index doesn't exist or the handle isn't of the given type, returns
  // an invalid handle.
  // Note that the caller is responsible for closing the returned handle, if it
  // is valid.
  SerializedHandle TakeHandleOfTypeAtIndex(size_t index,
                                           SerializedHandle::Type type) const;

  // Helper functions to return shared memory, socket or file handles passed in
  // the params struct.
  // If the index has a valid handle of the given type, it will be placed in the
  // output parameter, the corresponding slot in the list will be set to an
  // invalid handle, and the function will return true. If the handle doesn't
  // exist or is a different type, the functions will return false and the
  // output parameter will be untouched.
  //
  // Note: 1) the handle could still be a "null" or invalid handle of the right
  //          type and the functions will succeed.
  //       2) the caller is responsible for closing the returned handle, if it
  //          is valid.
  bool TakeSharedMemoryHandleAtIndex(size_t index,
                                     base::SharedMemoryHandle* handle) const;
  bool TakeSocketHandleAtIndex(size_t index,
                               IPC::PlatformFileForTransit* handle) const;
  bool TakeFileHandleAtIndex(size_t index,
                             IPC::PlatformFileForTransit* handle) const;
  void TakeAllSharedMemoryHandles(
      std::vector<base::SharedMemoryHandle>* handles) const;

  // Appends the given handle to the list of handles sent with the call or
  // reply.
  void AppendHandle(const SerializedHandle& handle) const;

 protected:
  ResourceMessageParams();
  ResourceMessageParams(PP_Resource resource, int32_t sequence);

  virtual void Serialize(IPC::Message* msg) const;
  virtual bool Deserialize(const IPC::Message* msg, PickleIterator* iter);

  // Writes everything except the handles to |msg|.
  void WriteHeader(IPC::Message* msg) const;
  // Writes the handles to |msg|.
  void WriteHandles(IPC::Message* msg) const;
  // Matching deserialize helpers.
  bool ReadHeader(const IPC::Message* msg, PickleIterator* iter);
  bool ReadHandles(const IPC::Message* msg, PickleIterator* iter);

 private:
  class SerializedHandles
      : public base::RefCountedThreadSafe<SerializedHandles> {
   public:
    SerializedHandles();
    ~SerializedHandles();

    void set_should_close(bool value) { should_close_ = value; }
    std::vector<SerializedHandle>& data() { return data_; }

   private:
    friend class base::RefCountedThreadSafe<SerializedHandles>;

    // Whether the handles stored in |data_| should be closed when this object
    // goes away.
    //
    // It is set to true by ResourceMessageParams::Deserialize(), so that the
    // receiving side of the params (the host side for
    // ResourceMessageCallParams; the plugin side for
    // ResourceMessageReplyParams) will close those handles which haven't been
    // taken using any of the Take*() methods.
    bool should_close_;
    std::vector<SerializedHandle> data_;
  };

  PP_Resource pp_resource_;

  // Identifier for this message. Sequence numbers are quasi-unique within a
  // resource, but will overlap between different resource objects.
  //
  // If you send a lot of messages, the ID may wrap around. This is OK. All IDs
  // are valid and 0 and -1 aren't special, so those cases won't confuse us.
  // In practice, if you send more than 4 billion messages for a resource, the
  // old ones will be long gone and there will be no collisions.
  //
  // If there is a malicious plugin (or exceptionally bad luck) that causes a
  // wraparound and collision the worst that will happen is that we can get
  // confused between different callbacks. But since these can only cause
  // confusion within the plugin and within callbacks on the same resource,
  // there shouldn't be a security problem.
  int32_t sequence_;

  // A list of all handles transferred in the message. Handles go here so that
  // the NaCl adapter can extract them generally when it rewrites them to
  // go between Windows and NaCl (Posix) apps.
  // TODO(yzshen): Mark it as mutable so that we can take/append handles using a
  // const reference. We need to change all the callers and make it not mutable.
  mutable scoped_refptr<SerializedHandles> handles_;
};

// Parameters common to all ResourceMessage "Call" requests.
class PPAPI_PROXY_EXPORT ResourceMessageCallParams
    : public ResourceMessageParams {
 public:
  ResourceMessageCallParams();
  ResourceMessageCallParams(PP_Resource resource, int32_t sequence);
  virtual ~ResourceMessageCallParams();

  void set_has_callback() { has_callback_ = true; }
  bool has_callback() const { return has_callback_; }

  virtual void Serialize(IPC::Message* msg) const OVERRIDE;
  virtual bool Deserialize(const IPC::Message* msg,
                           PickleIterator* iter) OVERRIDE;

 private:
  bool has_callback_;
};

// Parameters common to all ResourceMessage "Reply" requests.
class PPAPI_PROXY_EXPORT ResourceMessageReplyParams
    : public ResourceMessageParams {
 public:
  ResourceMessageReplyParams();
  ResourceMessageReplyParams(PP_Resource resource, int32_t sequence);
  virtual ~ResourceMessageReplyParams();

  void set_result(int32_t r) { result_ = r; }
  int32_t result() const { return result_; }

  virtual void Serialize(IPC::Message* msg) const OVERRIDE;
  virtual bool Deserialize(const IPC::Message* msg,
                           PickleIterator* iter) OVERRIDE;

  // Writes everything except the handles to |msg|.
  void WriteReplyHeader(IPC::Message* msg) const;

 private:
  // Pepper "result code" for the callback.
  int32_t result_;
};

}  // namespace proxy
}  // namespace ppapi

namespace IPC {

template <> struct PPAPI_PROXY_EXPORT
ParamTraits<ppapi::proxy::ResourceMessageCallParams> {
  typedef ppapi::proxy::ResourceMessageCallParams param_type;
  static void Write(Message* m, const param_type& p) {
    p.Serialize(m);
  }
  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
    return r->Deserialize(m, iter);
  }
  static void Log(const param_type& p, std::string* l) {
  }
};

template <> struct PPAPI_PROXY_EXPORT
ParamTraits<ppapi::proxy::ResourceMessageReplyParams> {
  typedef ppapi::proxy::ResourceMessageReplyParams param_type;
  static void Write(Message* m, const param_type& p) {
    p.Serialize(m);
  }
  static bool Read(const Message* m, PickleIterator* iter, param_type* r) {
    return r->Deserialize(m, iter);
  }
  static void Log(const param_type& p, std::string* l) {
  }
};

}  // namespace IPC

#endif  // PPAPI_PROXY_RESOURCE_MESSAGE_PARAMS_H_
