Chromium Code Reviews| Index: ppapi/proxy/ppp_content_decryptor_private_proxy.cc |
| diff --git a/ppapi/proxy/ppp_content_decryptor_private_proxy.cc b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f8b7fcd81f2f2616c8e3e8715a369d47312fadd9 |
| --- /dev/null |
| +++ b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc |
| @@ -0,0 +1,299 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "ppapi/proxy/ppp_content_decryptor_private_proxy.h" |
| + |
| +#include "base/platform_file.h" |
| +#include "ppapi/c/pp_bool.h" |
| +#include "ppapi/c/ppb_core.h" |
| +#include "ppapi/proxy/host_dispatcher.h" |
| +#include "ppapi/proxy/plugin_globals.h" |
| +#include "ppapi/proxy/plugin_resource_tracker.h" |
| +#include "ppapi/proxy/ppapi_messages.h" |
| +#include "ppapi/proxy/ppb_buffer_proxy.h" |
| +#include "ppapi/proxy/serialized_var.h" |
| +#include "ppapi/thunk/enter.h" |
| +#include "ppapi/thunk/ppb_buffer_api.h" |
| +#include "ppapi/thunk/ppb_buffer_trusted_api.h" |
| +#include "ppapi/thunk/ppb_instance_api.h" |
| +#include "ppapi/thunk/thunk.h" |
| + |
| +using ppapi::thunk::EnterResourceNoLock; |
| +using ppapi::thunk::PPB_Buffer_API; |
| +using ppapi::thunk::PPB_BufferTrusted_API; |
| +using ppapi::thunk::PPB_Instance_API; |
| + |
| +namespace ppapi { |
| +namespace proxy { |
| + |
| +namespace { |
| + |
| +PP_Bool DescribeHostBufferResource(PP_Resource resource, uint32_t* size) { |
| + EnterResourceNoLock<PPB_Buffer_API> enter(resource, true); |
| + if (enter.failed()) |
| + return PP_FALSE; |
| + return enter.object()->Describe(size); |
| +} |
| + |
| +PP_Bool ShareHostBufferResourceToPlugin( |
| + HostDispatcher* dispatcher, |
| + PP_Resource resource, |
| + base::SharedMemoryHandle* shared_mem_handle) { |
| + if (!dispatcher || resource == 0 || !shared_mem_handle) |
| + return PP_FALSE; |
| + EnterResourceNoLock<PPB_BufferTrusted_API> enter(resource, true); |
| + if (enter.failed()) |
| + return PP_FALSE; |
| + int handle; |
| + int32_t result = enter.object()->GetSharedMemory(&handle); |
| + if (result != PP_OK) |
| + return PP_FALSE; |
| + base::PlatformFile platform_file = |
| + #if defined(OS_WIN) |
| + reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle)); |
|
dmichael (off chromium)
2012/08/16 17:02:28
It's a little stupid the way we've copied/pasted t
Tom Finegan
2012/08/16 18:10:58
Done.
|
| + #elif defined(OS_POSIX) |
| + handle; |
| + #else |
| + #error Not implemented. |
| + #endif |
| + |
| + *shared_mem_handle = dispatcher->ShareHandleWithRemote(platform_file, false); |
| + return PP_TRUE; |
| +} |
| + |
| +PP_Bool GenerateKeyRequest(PP_Instance instance, |
| + PP_Var key_system, |
| + PP_Var init_data) { |
| + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| + if (!dispatcher) { |
| + NOTREACHED(); |
| + return PP_FALSE; |
| + } |
| + |
| + return PP_FromBool(dispatcher->Send( |
| + new PpapiMsg_PPPContentDecryptor_GenerateKeyRequest( |
| + API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, |
| + instance, |
| + SerializedVarSendInput(dispatcher, key_system), |
| + SerializedVarSendInput(dispatcher, init_data)))); |
| +} |
| + |
| +PP_Bool AddKey(PP_Instance instance, |
| + PP_Var session_id, |
| + PP_Var key) { |
| + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| + if (!dispatcher) { |
| + NOTREACHED(); |
| + return PP_FALSE; |
| + } |
| + |
| + return PP_FromBool(dispatcher->Send( |
| + new PpapiMsg_PPPContentDecryptor_AddKey( |
| + API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, |
| + instance, |
| + SerializedVarSendInput(dispatcher, session_id), |
| + SerializedVarSendInput(dispatcher, key)))); |
| +} |
| + |
| +PP_Bool CancelKeyRequest(PP_Instance instance, PP_Var session_id) { |
| + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| + if (!dispatcher) { |
| + NOTREACHED(); |
| + return PP_FALSE; |
| + } |
| + |
| + return PP_FromBool(dispatcher->Send( |
| + new PpapiMsg_PPPContentDecryptor_CancelKeyRequest( |
| + API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, |
| + instance, |
| + SerializedVarSendInput(dispatcher, session_id)))); |
| +} |
| + |
| +PP_Bool Decrypt(PP_Instance instance, |
| + PP_Resource encrypted_block, |
| + int32_t request_id) { |
| + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| + if (!dispatcher) { |
| + NOTREACHED(); |
| + return PP_FALSE; |
| + } |
| + const PPB_Core* core = static_cast<const PPB_Core*>( |
| + dispatcher->local_get_interface()(PPB_CORE_INTERFACE)); |
| + if (!core) { |
| + NOTREACHED(); |
| + return PP_FALSE; |
| + } |
| + |
| + // We need to take a ref on the resource now. The browser may drop |
| + // references once we return from here, but we're sending an asynchronous |
| + // message. The plugin side takes ownership of that reference. |
| + core->AddRefResource(encrypted_block); |
| + |
| + HostResource host_resource; |
| + host_resource.SetHostResource(instance, encrypted_block); |
| + |
| + uint32_t size = 0; |
| + if (DescribeHostBufferResource(encrypted_block, &size) == PP_FALSE) |
| + return PP_FALSE; |
| + |
| + base::SharedMemoryHandle handle; |
| + if (ShareHostBufferResourceToPlugin(dispatcher, |
| + encrypted_block, |
| + &handle) == PP_FALSE) |
| + return PP_FALSE; |
| + |
| + PPPDecryptor_Buffer buffer; |
| + buffer.resource = host_resource; |
| + buffer.handle = handle; |
| + buffer.size = size; |
| + |
| + return PP_FromBool(dispatcher->Send( |
| + new PpapiMsg_PPPContentDecryptor_Decrypt( |
| + API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, |
| + instance, |
| + buffer, |
| + request_id))); |
| +} |
| + |
| +PP_Bool DecryptAndDecode(PP_Instance instance, |
| + PP_Resource encrypted_block, |
| + int32_t request_id) { |
| + HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| + if (!dispatcher) { |
| + NOTREACHED(); |
| + return PP_FALSE; |
| + } |
| + |
| + HostResource host_resource; |
| + host_resource.SetHostResource(instance, encrypted_block); |
| + |
| + return PP_FromBool(dispatcher->Send( |
| + new PpapiMsg_PPPContentDecryptor_DecryptAndDecode( |
| + API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, |
| + instance, |
| + host_resource, |
| + request_id))); |
| +} |
| + |
| +static const PPP_ContentDecryptor_Private content_decryptor_interface = { |
| + &GenerateKeyRequest, |
| + &AddKey, |
| + &CancelKeyRequest, |
| + &Decrypt, |
| + &DecryptAndDecode |
| +}; |
| + |
| +InterfaceProxy* CreateContentDecryptorPPPProxy(Dispatcher* dispatcher) { |
| + return new PPP_ContentDecryptor_Private_Proxy(dispatcher); |
| +} |
| + |
| +} // namespace |
| + |
| +PPP_ContentDecryptor_Private_Proxy::PPP_ContentDecryptor_Private_Proxy( |
| + Dispatcher* dispatcher) |
| + : InterfaceProxy(dispatcher), |
| + ppp_decryptor_impl_(NULL) { |
| + if (dispatcher->IsPlugin()) { |
| + ppp_decryptor_impl_ = static_cast<const PPP_ContentDecryptor_Private*>( |
| + dispatcher->local_get_interface()( |
| + PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE)); |
| + } |
| +} |
| + |
| +PPP_ContentDecryptor_Private_Proxy::~PPP_ContentDecryptor_Private_Proxy() { |
| +} |
| + |
| +// static |
| +const PPP_ContentDecryptor_Private* |
| + PPP_ContentDecryptor_Private_Proxy::GetProxyInterface() { |
| + return &content_decryptor_interface; |
| +} |
| + |
| +bool PPP_ContentDecryptor_Private_Proxy::OnMessageReceived( |
| + const IPC::Message& msg) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(PPP_ContentDecryptor_Private_Proxy, msg) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_GenerateKeyRequest, |
| + OnMsgGenerateKeyRequest) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_AddKey, |
| + OnMsgAddKey) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_CancelKeyRequest, |
| + OnMsgCancelKeyRequest) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_Decrypt, |
| + OnMsgDecrypt) |
| + IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_DecryptAndDecode, |
| + OnMsgDecryptAndDecode) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + DCHECK(handled); |
| + return handled; |
| +} |
| + |
| +void PPP_ContentDecryptor_Private_Proxy::OnMsgGenerateKeyRequest( |
| + PP_Instance instance, |
| + SerializedVarReceiveInput key_system, |
| + SerializedVarReceiveInput init_data) { |
| + if (ppp_decryptor_impl_) { |
| + CallWhileUnlocked(ppp_decryptor_impl_->GenerateKeyRequest, |
| + instance, |
| + key_system.Get(dispatcher()), |
| + init_data.Get(dispatcher())); |
| + } |
| +} |
| + |
| +void PPP_ContentDecryptor_Private_Proxy::OnMsgAddKey( |
| + PP_Instance instance, |
| + SerializedVarReceiveInput session_id, |
| + SerializedVarReceiveInput key) { |
| + if (ppp_decryptor_impl_) { |
| + CallWhileUnlocked(ppp_decryptor_impl_->AddKey, |
| + instance, |
| + session_id.Get(dispatcher()), |
| + key.Get(dispatcher())); |
| + } |
| +} |
| + |
| +void PPP_ContentDecryptor_Private_Proxy::OnMsgCancelKeyRequest( |
| + PP_Instance instance, |
| + SerializedVarReceiveInput session_id) { |
| + if (ppp_decryptor_impl_) { |
| + CallWhileUnlocked(CancelKeyRequest, |
| + instance, |
| + session_id.Get(dispatcher())); |
| + } |
| +} |
| + |
| +void PPP_ContentDecryptor_Private_Proxy::OnMsgDecrypt( |
| + PP_Instance instance, |
| + PPPDecryptor_Buffer encrypted_buffer, |
| + int32_t request_id) { |
| + if (ppp_decryptor_impl_) { |
| + PP_Resource plugin_resource = |
| + PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource, |
| + encrypted_buffer.handle, |
| + encrypted_buffer.size); |
| + CallWhileUnlocked(ppp_decryptor_impl_->Decrypt, |
| + instance, |
| + plugin_resource, |
| + request_id); |
| + } |
| +} |
| + |
| +void PPP_ContentDecryptor_Private_Proxy::OnMsgDecryptAndDecode( |
| + PP_Instance instance, |
| + const HostResource& encrypted_block, |
| + int32_t request_id) { |
| + if (ppp_decryptor_impl_) { |
| + PP_Resource plugin_resource = |
| + PluginGlobals::Get()->plugin_resource_tracker()-> |
| + PluginResourceForHostResource(encrypted_block); |
| + CallWhileUnlocked(ppp_decryptor_impl_->DecryptAndDecode, |
| + instance, |
| + plugin_resource, |
| + request_id); |
| + } |
| +} |
| + |
| +} // namespace proxy |
| +} // namespace ppapi |