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/resource_creation_api.h"
20 #include "ppapi/thunk/thunk.h"
25 Buffer::Buffer(const HostResource
& resource
,
26 const base::SharedMemoryHandle
& shm_handle
,
28 : Resource(OBJECT_IS_PROXY
, resource
),
29 shm_(shm_handle
, false),
38 thunk::PPB_Buffer_API
* Buffer::AsPPB_Buffer_API() {
42 PP_Bool
Buffer::Describe(uint32_t* size_in_bytes
) {
43 *size_in_bytes
= size_
;
47 PP_Bool
Buffer::IsMapped() {
48 return PP_FromBool(map_count_
> 0);
52 if (map_count_
++ == 0)
57 void Buffer::Unmap() {
58 if (--map_count_
== 0)
62 int32_t Buffer::GetSharedMemory(base::SharedMemory
** out_handle
) {
64 return PP_ERROR_NOTSUPPORTED
;
67 PPB_Buffer_Proxy::PPB_Buffer_Proxy(Dispatcher
* dispatcher
)
68 : InterfaceProxy(dispatcher
) {
71 PPB_Buffer_Proxy::~PPB_Buffer_Proxy() {
75 PP_Resource
PPB_Buffer_Proxy::CreateProxyResource(PP_Instance instance
,
77 PluginDispatcher
* dispatcher
= PluginDispatcher::GetForInstance(instance
);
82 ppapi::proxy::SerializedHandle shm_handle
;
83 dispatcher
->Send(new PpapiHostMsg_PPBBuffer_Create(
84 API_ID_PPB_BUFFER
, instance
, size
, &result
, &shm_handle
));
85 if (result
.is_null() || !shm_handle
.IsHandleValid() ||
86 !shm_handle
.is_shmem())
89 return AddProxyResource(result
, shm_handle
.shmem(), size
);
93 PP_Resource
PPB_Buffer_Proxy::AddProxyResource(
94 const HostResource
& resource
,
95 base::SharedMemoryHandle shm_handle
,
97 return (new Buffer(resource
, shm_handle
, size
))->GetReference();
100 bool PPB_Buffer_Proxy::OnMessageReceived(const IPC::Message
& msg
) {
102 IPC_BEGIN_MESSAGE_MAP(PPB_Buffer_Proxy
, msg
)
103 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBBuffer_Create
, OnMsgCreate
)
104 IPC_MESSAGE_UNHANDLED(handled
= false)
105 IPC_END_MESSAGE_MAP()
106 // TODO(brettw) handle bad messages!
110 void PPB_Buffer_Proxy::OnMsgCreate(
111 PP_Instance instance
,
113 HostResource
* result_resource
,
114 ppapi::proxy::SerializedHandle
* result_shm_handle
) {
115 // Overwritten below on success.
116 result_shm_handle
->set_null_shmem();
117 HostDispatcher
* dispatcher
= HostDispatcher::GetForInstance(instance
);
120 if (!dispatcher
->permissions().HasPermission(ppapi::PERMISSION_DEV
))
123 thunk::EnterResourceCreation
enter(instance
);
126 PP_Resource local_buffer_resource
= enter
.functions()->CreateBuffer(instance
,
128 if (local_buffer_resource
== 0)
131 thunk::EnterResourceNoLock
<thunk::PPB_Buffer_API
> trusted_buffer(
132 local_buffer_resource
, false);
133 if (trusted_buffer
.failed())
135 base::SharedMemory
* local_shm
;
136 if (trusted_buffer
.object()->GetSharedMemory(&local_shm
) != PP_OK
)
139 result_resource
->SetHostResource(instance
, local_buffer_resource
);
141 result_shm_handle
->set_shmem(
142 dispatcher
->ShareSharedMemoryHandleWithRemote(local_shm
->handle()), size
);