1// Copyright (c) 2013 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 "chrome/renderer/pepper/pepper_shared_memory_message_filter.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/memory/shared_memory.h"
9#include "base/process/process_handle.h"
10#include "content/public/common/content_client.h"
11#include "content/public/renderer/pepper_plugin_instance.h"
12#include "content/public/renderer/render_thread.h"
13#include "content/public/renderer/renderer_ppapi_host.h"
14#include "ppapi/host/ppapi_host.h"
15#include "ppapi/proxy/ppapi_messages.h"
16#include "ppapi/shared_impl/var_tracker.h"
17
18PepperSharedMemoryMessageFilter::PepperSharedMemoryMessageFilter(
19    content::RendererPpapiHost* host)
20    : InstanceMessageFilter(host->GetPpapiHost()), host_(host) {}
21
22PepperSharedMemoryMessageFilter::~PepperSharedMemoryMessageFilter() {}
23
24bool PepperSharedMemoryMessageFilter::OnInstanceMessageReceived(
25    const IPC::Message& msg) {
26  bool handled = true;
27  IPC_BEGIN_MESSAGE_MAP(PepperSharedMemoryMessageFilter, msg)
28    IPC_MESSAGE_HANDLER(PpapiHostMsg_SharedMemory_CreateSharedMemory,
29                        OnHostMsgCreateSharedMemory)
30    IPC_MESSAGE_UNHANDLED(handled = false)
31  IPC_END_MESSAGE_MAP()
32  return handled;
33}
34
35bool PepperSharedMemoryMessageFilter::Send(IPC::Message* msg) {
36  return host_->GetPpapiHost()->Send(msg);
37}
38
39void PepperSharedMemoryMessageFilter::OnHostMsgCreateSharedMemory(
40    PP_Instance instance,
41    uint32_t size,
42    int* host_handle_id,
43    ppapi::proxy::SerializedHandle* plugin_handle) {
44  plugin_handle->set_null_shmem();
45  *host_handle_id = -1;
46  scoped_ptr<base::SharedMemory> shm(content::RenderThread::Get()
47                                         ->HostAllocateSharedMemoryBuffer(size)
48                                         .Pass());
49  if (!shm.get())
50    return;
51
52  base::SharedMemoryHandle host_shm_handle;
53  shm->ShareToProcess(base::GetCurrentProcessHandle(), &host_shm_handle);
54  *host_handle_id =
55      content::PepperPluginInstance::Get(instance)
56          ->GetVarTracker()
57          ->TrackSharedMemoryHandle(instance, host_shm_handle, size);
58
59  base::PlatformFile host_handle =
60#if defined(OS_WIN)
61      host_shm_handle;
62#elif defined(OS_POSIX)
63      host_shm_handle.fd;
64#else
65#error Not implemented.
66#endif
67  // We set auto_close to false since we need our file descriptor to
68  // actually be duplicated on linux. The shared memory destructor will
69  // close the original handle for us.
70  plugin_handle->set_shmem(host_->ShareHandleWithRemote(host_handle, false),
71                           size);
72}
73