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.
5 #include "ppapi/proxy/ppb_buffer_proxy.h"
9 #include "base/logging.h"
10 #include "build/build_config.h"
11 #include "ppapi/c/pp_completion_callback.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/pp_resource.h"
14 #include "ppapi/c/dev/ppb_buffer_dev.h"
15 #include "ppapi/proxy/host_dispatcher.h"
16 #include "ppapi/proxy/plugin_dispatcher.h"
17 #include "ppapi/proxy/ppapi_messages.h"
18 #include "ppapi/thunk/enter.h"
19 #include "ppapi/thunk/ppb_buffer_trusted_api.h"
20 #include "ppapi/thunk/resource_creation_api.h"
21 #include "ppapi/thunk/thunk.h"
26 Buffer::Buffer(const HostResource
& resource
,
27 const base::SharedMemoryHandle
& shm_handle
,
29 : Resource(OBJECT_IS_PROXY
, resource
),
30 shm_(shm_handle
, false),
39 thunk::PPB_Buffer_API
* Buffer::AsPPB_Buffer_API() {
43 PP_Bool
Buffer::Describe(uint32_t* size_in_bytes
) {
44 *size_in_bytes
= size_
;
48 PP_Bool
Buffer::IsMapped() {
49 return PP_FromBool(map_count_
> 0);
53 if (map_count_
++ == 0)
58 void Buffer::Unmap() {
59 if (--map_count_
== 0)
63 PPB_Buffer_Proxy::PPB_Buffer_Proxy(Dispatcher
* dispatcher
)
64 : InterfaceProxy(dispatcher
) {
67 PPB_Buffer_Proxy::~PPB_Buffer_Proxy() {
71 PP_Resource
PPB_Buffer_Proxy::CreateProxyResource(PP_Instance instance
,
73 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance
);
78 ppapi::proxy::SerializedHandle shm_handle
;
79 dispatcher
->Send(new PpapiHostMsg_PPBBuffer_Create(
80 API_ID_PPB_BUFFER
, instance
, size
, &result
, &shm_handle
));
81 if (result
.is_null() || !shm_handle
.IsHandleValid() ||
82 !shm_handle
.is_shmem())
85 return AddProxyResource(result
, shm_handle
.shmem(), size
);
89 PP_Resource
PPB_Buffer_Proxy::AddProxyResource(
90 const HostResource
& resource
,
91 base::SharedMemoryHandle shm_handle
,
93 return (new Buffer(resource
, shm_handle
, size
))->GetReference();
96 bool PPB_Buffer_Proxy::OnMessageReceived(const IPC::Message
& msg
) {
98 IPC_BEGIN_MESSAGE_MAP(PPB_Buffer_Proxy
, msg
)
99 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBBuffer_Create
, OnMsgCreate
)
100 IPC_MESSAGE_UNHANDLED(handled
= false)
101 IPC_END_MESSAGE_MAP()
102 // TODO(brettw) handle bad messages!
106 void PPB_Buffer_Proxy::OnMsgCreate(
107 PP_Instance instance
,
109 HostResource
* result_resource
,
110 ppapi::proxy::SerializedHandle
* result_shm_handle
) {
111 // Overwritten below on success.
112 result_shm_handle
->set_null_shmem();
113 HostDispatcher
* dispatcher
= HostDispatcher::GetForInstance(instance
);
116 if (!dispatcher
->permissions().HasPermission(ppapi::PERMISSION_DEV
))
119 thunk::EnterResourceCreation
enter(instance
);
122 PP_Resource local_buffer_resource
= enter
.functions()->CreateBuffer(instance
,
124 if (local_buffer_resource
== 0)
127 thunk::EnterResourceNoLock
<thunk::PPB_BufferTrusted_API
> trusted_buffer(
128 local_buffer_resource
, false);
129 if (trusted_buffer
.failed())
132 if (trusted_buffer
.object()->GetSharedMemory(&local_fd
) != PP_OK
)
135 result_resource
->SetHostResource(instance
, local_buffer_resource
);
137 // TODO(piman/brettw): Change trusted interface to return a PP_FileHandle,
138 // those casts are ugly.
139 base::PlatformFile platform_file
=
141 reinterpret_cast<HANDLE
>(static_cast<intptr_t>(local_fd
));
142 #elif defined(OS_POSIX)
145 #error Not implemented.
147 result_shm_handle
->set_shmem(
148 dispatcher
->ShareHandleWithRemote(platform_file
, false), size
);