blob: ec4b1ea51b4d6783ebfe83ce81777af1a0edb77e [file] [log] [blame]
[email protected]465faa22011-02-08 16:31:461// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]43a40202010-11-12 16:25:012// 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/ppb_buffer_proxy.h"
6
7#include <vector>
8
9#include "base/logging.h"
10#include "build/build_config.h"
11#include "ppapi/c/pp_completion_callback.h"
[email protected]32523382011-06-10 02:30:0012#include "ppapi/c/pp_errors.h"
[email protected]43a40202010-11-12 16:25:0113#include "ppapi/c/pp_resource.h"
14#include "ppapi/c/dev/ppb_buffer_dev.h"
[email protected]32523382011-06-10 02:30:0015#include "ppapi/proxy/host_dispatcher.h"
[email protected]43a40202010-11-12 16:25:0116#include "ppapi/proxy/plugin_dispatcher.h"
17#include "ppapi/proxy/plugin_resource.h"
18#include "ppapi/proxy/ppapi_messages.h"
[email protected]32523382011-06-10 02:30:0019#include "ppapi/thunk/enter.h"
[email protected]9815108e2011-05-27 21:50:2820#include "ppapi/thunk/ppb_buffer_api.h"
[email protected]32523382011-06-10 02:30:0021#include "ppapi/thunk/ppb_buffer_trusted_api.h"
[email protected]9815108e2011-05-27 21:50:2822#include "ppapi/thunk/thunk.h"
[email protected]43a40202010-11-12 16:25:0123
24namespace pp {
25namespace proxy {
26
[email protected]9815108e2011-05-27 21:50:2827namespace {
28
29InterfaceProxy* CreateBufferProxy(Dispatcher* dispatcher,
30 const void* target_interface) {
31 return new PPB_Buffer_Proxy(dispatcher, target_interface);
32}
33
34} // namespace
35
36class Buffer : public ppapi::thunk::PPB_Buffer_API,
37 public PluginResource {
[email protected]43a40202010-11-12 16:25:0138 public:
[email protected]f24448db2011-01-27 20:40:3939 Buffer(const HostResource& resource,
[email protected]32523382011-06-10 02:30:0040 const base::SharedMemoryHandle& shm_handle,
[email protected]f24448db2011-01-27 20:40:3941 uint32_t size);
[email protected]43a40202010-11-12 16:25:0142 virtual ~Buffer();
43
44 // Resource overrides.
[email protected]9815108e2011-05-27 21:50:2845 virtual Buffer* AsBuffer() OVERRIDE;
[email protected]43a40202010-11-12 16:25:0146
[email protected]9815108e2011-05-27 21:50:2847 // ResourceObjectBase overries.
[email protected]cd910b92011-06-01 07:19:3148 virtual ppapi::thunk::PPB_Buffer_API* AsPPB_Buffer_API() OVERRIDE;
[email protected]43a40202010-11-12 16:25:0149
[email protected]9815108e2011-05-27 21:50:2850 // PPB_Buffer_API implementation.
51 virtual PP_Bool Describe(uint32_t* size_in_bytes) OVERRIDE;
52 virtual PP_Bool IsMapped() OVERRIDE;
53 virtual void* Map() OVERRIDE;
54 virtual void Unmap() OVERRIDE;
[email protected]43a40202010-11-12 16:25:0155
56 private:
[email protected]32523382011-06-10 02:30:0057 base::SharedMemory shm_;
[email protected]867b76d632010-12-02 00:09:0758 uint32_t size_;
[email protected]43a40202010-11-12 16:25:0159 void* mapped_data_;
[email protected]81fc59f2011-06-14 19:28:4160 int map_count_;
[email protected]43a40202010-11-12 16:25:0161
62 DISALLOW_COPY_AND_ASSIGN(Buffer);
63};
64
[email protected]f24448db2011-01-27 20:40:3965Buffer::Buffer(const HostResource& resource,
[email protected]32523382011-06-10 02:30:0066 const base::SharedMemoryHandle& shm_handle,
[email protected]f24448db2011-01-27 20:40:3967 uint32_t size)
68 : PluginResource(resource),
[email protected]32523382011-06-10 02:30:0069 shm_(shm_handle, false),
[email protected]43a40202010-11-12 16:25:0170 size_(size),
[email protected]81fc59f2011-06-14 19:28:4171 mapped_data_(NULL),
72 map_count_(0) {
[email protected]43a40202010-11-12 16:25:0173}
74
75Buffer::~Buffer() {
76 Unmap();
77}
78
[email protected]9815108e2011-05-27 21:50:2879Buffer* Buffer::AsBuffer() {
80 return this;
81}
82
[email protected]cd910b92011-06-01 07:19:3183ppapi::thunk::PPB_Buffer_API* Buffer::AsPPB_Buffer_API() {
[email protected]9815108e2011-05-27 21:50:2884 return this;
85}
86
87PP_Bool Buffer::Describe(uint32_t* size_in_bytes) {
88 *size_in_bytes = size_;
89 return PP_TRUE;
90}
91
92PP_Bool Buffer::IsMapped() {
93 return PP_FromBool(!!mapped_data_);
94}
95
[email protected]43a40202010-11-12 16:25:0196void* Buffer::Map() {
[email protected]81fc59f2011-06-14 19:28:4197 if (map_count_++ == 0)
[email protected]32523382011-06-10 02:30:0098 shm_.Map(size_);
99 return shm_.memory();
[email protected]43a40202010-11-12 16:25:01100}
101
102void Buffer::Unmap() {
[email protected]81fc59f2011-06-14 19:28:41103 if (--map_count_ == 0)
104 shm_.Unmap();
[email protected]43a40202010-11-12 16:25:01105}
106
[email protected]43a40202010-11-12 16:25:01107PPB_Buffer_Proxy::PPB_Buffer_Proxy(Dispatcher* dispatcher,
108 const void* target_interface)
109 : InterfaceProxy(dispatcher, target_interface) {
110}
111
112PPB_Buffer_Proxy::~PPB_Buffer_Proxy() {
113}
114
[email protected]465faa22011-02-08 16:31:46115// static
116const InterfaceProxy::Info* PPB_Buffer_Proxy::GetInfo() {
117 static const Info info = {
[email protected]9815108e2011-05-27 21:50:28118 ppapi::thunk::GetPPB_Buffer_Thunk(),
[email protected]465faa22011-02-08 16:31:46119 PPB_BUFFER_DEV_INTERFACE,
120 INTERFACE_ID_PPB_BUFFER,
121 false,
122 &CreateBufferProxy,
123 };
124 return &info;
[email protected]43a40202010-11-12 16:25:01125}
126
[email protected]9815108e2011-05-27 21:50:28127// static
128PP_Resource PPB_Buffer_Proxy::CreateProxyResource(PP_Instance instance,
129 uint32_t size) {
130 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
131 if (!dispatcher)
132 return 0;
133
134 HostResource result;
[email protected]32523382011-06-10 02:30:00135 base::SharedMemoryHandle shm_handle = base::SharedMemory::NULLHandle();
[email protected]9815108e2011-05-27 21:50:28136 dispatcher->Send(new PpapiHostMsg_PPBBuffer_Create(
137 INTERFACE_ID_PPB_BUFFER, instance, size,
138 &result, &shm_handle));
[email protected]32523382011-06-10 02:30:00139 if (result.is_null() || !base::SharedMemory::IsHandleValid(shm_handle))
[email protected]9815108e2011-05-27 21:50:28140 return 0;
141
[email protected]32523382011-06-10 02:30:00142 linked_ptr<Buffer> object(new Buffer(result, shm_handle, size));
[email protected]9815108e2011-05-27 21:50:28143 return PluginResourceTracker::GetInstance()->AddResource(object);
144}
145
[email protected]a95986a82010-12-24 06:19:28146bool PPB_Buffer_Proxy::OnMessageReceived(const IPC::Message& msg) {
147 bool handled = true;
[email protected]43a40202010-11-12 16:25:01148 IPC_BEGIN_MESSAGE_MAP(PPB_Buffer_Proxy, msg)
149 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBBuffer_Create, OnMsgCreate)
[email protected]a95986a82010-12-24 06:19:28150 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]43a40202010-11-12 16:25:01151 IPC_END_MESSAGE_MAP()
152 // TODO(brettw) handle bad messages!
[email protected]a95986a82010-12-24 06:19:28153 return handled;
[email protected]43a40202010-11-12 16:25:01154}
155
[email protected]32523382011-06-10 02:30:00156void PPB_Buffer_Proxy::OnMsgCreate(
157 PP_Instance instance,
158 uint32_t size,
159 HostResource* result_resource,
160 base::SharedMemoryHandle* result_shm_handle) {
161 // Overwritten below on success.
162 *result_shm_handle = base::SharedMemory::NULLHandle();
163 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
164 if (!dispatcher)
165 return;
166 PP_Resource local_buffer_resource =
167 ppb_buffer_target()->Create(instance, size);
168 if (local_buffer_resource == 0)
169 return;
170 ::ppapi::thunk::EnterResourceNoLock< ::ppapi::thunk::PPB_BufferTrusted_API>
171 trusted_buffer(local_buffer_resource, false);
172 if (trusted_buffer.failed())
173 return;
174 int local_fd;
175 if (trusted_buffer.object()->GetSharedMemory(&local_fd) != PP_OK)
176 return;
177
178 result_resource->SetHostResource(instance, local_buffer_resource);
179
180 // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle,
181 // those casts are ugly.
182 base::PlatformFile platform_file =
183#if defined(OS_WIN)
184 reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd));
185#elif defined(OS_POSIX)
186 local_fd;
187#else
188 #error Not implemented.
189#endif
190 *result_shm_handle = dispatcher->ShareHandleWithRemote(platform_file, false);
[email protected]43a40202010-11-12 16:25:01191}
192
193} // namespace proxy
194} // namespace pp