1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/renderer/pepper/host_array_buffer_var.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <stdio.h>
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string.h>
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/logging.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/memory/shared_memory.h"
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/process/process_handle.h"
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/common/sandbox_util.h"
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/renderer/pepper/host_globals.h"
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/renderer/pepper/plugin_module.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/renderer/render_thread_impl.h"
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ppapi/c/pp_instance.h"
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using ppapi::ArrayBufferVar;
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using blink::WebArrayBuffer;
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace content {
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)HostArrayBufferVar::HostArrayBufferVar(uint32 size_in_bytes)
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : buffer_(WebArrayBuffer::create(size_in_bytes, 1 /* element_size */)),
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      valid_(true) {}
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)HostArrayBufferVar::HostArrayBufferVar(const WebArrayBuffer& buffer)
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : buffer_(buffer), valid_(true) {}
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)HostArrayBufferVar::HostArrayBufferVar(uint32 size_in_bytes,
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                       base::SharedMemoryHandle handle)
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    : buffer_(WebArrayBuffer::create(size_in_bytes, 1 /* element_size */)) {
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::SharedMemory s(handle, true);
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  valid_ = s.Map(size_in_bytes);
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (valid_) {
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    memcpy(buffer_.data(), s.memory(), size_in_bytes);
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    s.Unmap();
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)HostArrayBufferVar::~HostArrayBufferVar() {}
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void* HostArrayBufferVar::Map() {
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!valid_)
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return NULL;
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return buffer_.data();
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void HostArrayBufferVar::Unmap() {
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // We do not used shared memory on the host side. Nothing to do.
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)uint32 HostArrayBufferVar::ByteLength() { return buffer_.byteLength(); }
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool HostArrayBufferVar::CopyToNewShmem(
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PP_Instance instance,
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int* host_shm_handle_id,
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::SharedMemoryHandle* plugin_shm_handle) {
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<base::SharedMemory> shm(
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      RenderThread::Get()
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          ->HostAllocateSharedMemoryBuffer(ByteLength())
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          .release());
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!shm)
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  shm->Map(ByteLength());
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  memcpy(shm->memory(), Map(), ByteLength());
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  shm->Unmap();
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Duplicate the handle here; the SharedMemory destructor closes
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // its handle on us.
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  HostGlobals* hg = HostGlobals::Get();
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  PluginModule* pm = hg->GetModule(hg->GetModuleForInstance(instance));
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::ProcessId p = pm->GetPeerProcessId();
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (p == base::kNullProcessId) {
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // In-process, clone for ourselves.
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    p = base::GetCurrentProcId();
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::PlatformFile platform_file =
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_WIN)
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      shm->handle();
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#elif defined(OS_POSIX)
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      shm->handle().fd;
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#else
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#error Not implemented.
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  *plugin_shm_handle = BrokerGetFileHandleForProcess(platform_file, p, false);
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  *host_shm_handle_id = -1;
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace content
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)