diff options
23 files changed, 1617 insertions, 0 deletions
diff --git a/ppapi/cpp/private/content_decryptor_private.cc b/ppapi/cpp/private/content_decryptor_private.cc new file mode 100644 index 0000000..c2d95ed --- /dev/null +++ b/ppapi/cpp/private/content_decryptor_private.cc @@ -0,0 +1,239 @@ +// 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/cpp/private/content_decryptor_private.h" + +#include <cstring> // memcpy + +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/private/ppb_content_decryptor_private.h" +#include "ppapi/c/private/ppp_content_decryptor_private.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/instance_handle.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/module_impl.h" +#include "ppapi/cpp/var.h" + +namespace pp { + +namespace { + +static const char kPPPContentDecryptorInterface[] = + PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE; + +PP_Bool GenerateKeyRequest(PP_Instance instance, + PP_Var key_system_arg, + PP_Var init_data_arg) { + void* object = + Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); + if (!object) + return PP_FALSE; + + pp::Var key_system_var(pp::PASS_REF, key_system_arg); + if (key_system_var.is_string() == false) + return PP_FALSE; + + pp::Var init_data_var(pp::PASS_REF, init_data_arg); + if (init_data_var.is_array_buffer() == false) + return PP_FALSE; + pp::VarArrayBuffer init_data_array_buffer(init_data_var); + + return PP_FromBool( + static_cast<ContentDecryptor_Private*>(object)->GenerateKeyRequest( + key_system_var.AsString(), + init_data_array_buffer)); +} + +PP_Bool AddKey(PP_Instance instance, + PP_Var session_id_arg, + PP_Var key_arg) { + void* object = + Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); + if (!object) + return PP_FALSE; + + pp::Var session_id_var(pp::PASS_REF, session_id_arg); + if (session_id_var.is_string() == false) + return PP_FALSE; + + pp::Var key_var(pp::PASS_REF, key_arg); + if (key_var.is_array_buffer() == false) + return PP_FALSE; + pp::VarArrayBuffer key(key_var); + + return PP_FromBool( + static_cast<ContentDecryptor_Private*>(object)->AddKey( + session_id_var.AsString(), + key)); +} + +PP_Bool CancelKeyRequest(PP_Instance instance, + PP_Var session_id_arg) { + void* object = + Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); + if (!object) + return PP_FALSE; + + pp::Var session_id_var(pp::PASS_REF, session_id_arg); + if (session_id_var.is_string() == false) + return PP_FALSE; + + return PP_FromBool( + static_cast<ContentDecryptor_Private*>(object)-> + CancelKeyRequest(session_id_var.AsString())); +} + + +PP_Bool Decrypt(PP_Instance instance, + PP_Resource encrypted_resource, + int32_t request_id) { + void* object = + Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); + if (!object) + return PP_FALSE; + + pp::Buffer_Dev encrypted_block(encrypted_resource); + + return PP_FromBool( + static_cast<ContentDecryptor_Private*>(object)->Decrypt(encrypted_block, + request_id)); +} + +PP_Bool DecryptAndDecode(PP_Instance instance, + PP_Resource encrypted_resource, + int32_t request_id) { + void* object = + Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); + if (!object) + return PP_FALSE; + + pp::Buffer_Dev encrypted_block(encrypted_resource); + + return PP_FromBool( + static_cast<ContentDecryptor_Private*>(object)->DecryptAndDecode( + encrypted_block, + request_id)); +} + +const PPP_ContentDecryptor_Private ppp_content_decryptor = { + &GenerateKeyRequest, + &AddKey, + &CancelKeyRequest, + &Decrypt, + &DecryptAndDecode +}; + +template <> const char* interface_name<PPB_ContentDecryptor_Private>() { + return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE; +} + +} // namespace + +ContentDecryptor_Private::ContentDecryptor_Private(Instance* instance) + : associated_instance_(instance) { + Module::Get()->AddPluginInterface(kPPPContentDecryptorInterface, + &ppp_content_decryptor); + instance->AddPerInstanceObject(kPPPContentDecryptorInterface, this); +} + +ContentDecryptor_Private::~ContentDecryptor_Private() { + Instance::RemovePerInstanceObject(associated_instance_, + kPPPContentDecryptorInterface, + this); +} + +void ContentDecryptor_Private::NeedKey(const std::string& key_system, + const std::string& session_id, + pp::VarArrayBuffer init_data) { + // session_id can be empty here. + if (has_interface<PPB_ContentDecryptor_Private>()) { + pp::Var key_system_var(key_system); + pp::Var session_id_var(session_id); + + // TODO(tomfinegan): Host to plugin stuff needed for init_data? + + get_interface<PPB_ContentDecryptor_Private>()->NeedKey( + associated_instance_.pp_instance(), + key_system_var.pp_var(), + session_id_var.pp_var(), + init_data.pp_var()); + } +} + +void ContentDecryptor_Private::KeyAdded(const std::string& key_system, + const std::string& session_id) { + if (has_interface<PPB_ContentDecryptor_Private>()) { + pp::Var key_system_var(key_system); + pp::Var session_id_var(session_id); + get_interface<PPB_ContentDecryptor_Private>()->KeyAdded( + associated_instance_.pp_instance(), + key_system_var.pp_var(), + session_id_var.pp_var()); + } +} + +void ContentDecryptor_Private::KeyMessage(const std::string& key_system, + const std::string& session_id, + pp::Buffer_Dev message, + const std::string& default_url) { + if (has_interface<PPB_ContentDecryptor_Private>()) { + pp::Var key_system_var(key_system); + pp::Var session_id_var(session_id); + pp::Var default_url_var(default_url); + get_interface<PPB_ContentDecryptor_Private>()->KeyMessage( + associated_instance_.pp_instance(), + key_system_var.pp_var(), + session_id_var.pp_var(), + message.pp_resource(), + default_url_var.pp_var()); + } +} + +void ContentDecryptor_Private::KeyError(const std::string& key_system, + const std::string& session_id, + int32_t media_error, + int32_t system_code) { + if (has_interface<PPB_ContentDecryptor_Private>()) { + pp::Var key_system_var(key_system); + pp::Var session_id_var(session_id); + get_interface<PPB_ContentDecryptor_Private>()->KeyError( + associated_instance_.pp_instance(), + key_system_var.pp_var(), + session_id_var.pp_var(), + media_error, + system_code); + } +} + +void ContentDecryptor_Private::DeliverBlock(pp::Buffer_Dev decrypted_block, + int32_t request_id) { + if (has_interface<PPB_ContentDecryptor_Private>()) { + get_interface<PPB_ContentDecryptor_Private>()->DeliverBlock( + associated_instance_.pp_instance(), + decrypted_block.pp_resource(), + request_id); + } +} + +void ContentDecryptor_Private::DeliverFrame(pp::Buffer_Dev decrypted_frame, + int32_t request_id) { + if (has_interface<PPB_ContentDecryptor_Private>()) { + get_interface<PPB_ContentDecryptor_Private>()->DeliverFrame( + associated_instance_.pp_instance(), + decrypted_frame.pp_resource(), + request_id); + } +} + +void ContentDecryptor_Private::DeliverSamples(pp::Buffer_Dev decrypted_samples, + int32_t request_id) { + if (has_interface<PPB_ContentDecryptor_Private>()) { + get_interface<PPB_ContentDecryptor_Private>()->DeliverSamples( + associated_instance_.pp_instance(), + decrypted_samples.pp_resource(), + request_id); + } +} + +} // namespace pp diff --git a/ppapi/cpp/private/content_decryptor_private.h b/ppapi/cpp/private/content_decryptor_private.h new file mode 100644 index 0000000..f300ea0 --- /dev/null +++ b/ppapi/cpp/private/content_decryptor_private.h @@ -0,0 +1,68 @@ +// 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. + +#ifndef PPAPI_CPP_PRIVATE_CONTENT_DECRYPTOR_PRIVATE_H_ +#define PPAPI_CPP_PRIVATE_CONTENT_DECRYPTOR_PRIVATE_H_ + +#include "ppapi/c/private/ppb_content_decryptor_private.h" +#include "ppapi/c/private/ppp_content_decryptor_private.h" + +#include "ppapi/cpp/dev/buffer_dev.h" +#include "ppapi/cpp/instance_handle.h" +#include "ppapi/cpp/var.h" +#include "ppapi/cpp/var_array_buffer.h" + +namespace pp { + +class Instance; + +class ContentDecryptor_Private { + public: + explicit ContentDecryptor_Private(Instance* instance); + virtual ~ContentDecryptor_Private(); + + // PPP_ContentDecryptor_Private functions exposed as virtual functions + // for you to override. + // TODO(tomfinegan): This could be optimized to pass pp::Var instead of + // strings. The change would allow the CDM wrapper to reuse vars when + // replying to the browser. + virtual bool GenerateKeyRequest(const std::string& key_system, + pp::VarArrayBuffer init_data) = 0; + virtual bool AddKey(const std::string& session_id, + pp::VarArrayBuffer key) = 0; + virtual bool CancelKeyRequest(const std::string& session_id) = 0; + virtual bool Decrypt(pp::Buffer_Dev encrypted_buffer, + int32_t request_id) = 0; + virtual bool DecryptAndDecode(pp::Buffer_Dev encrypted_buffer, + int32_t request_id) = 0; + + // PPB_ContentDecryptor_Private methods for passing data from the decryptor + // to the browser. + void NeedKey(const std::string& key_system, + const std::string& session_id, + pp::VarArrayBuffer init_data); + void KeyAdded(const std::string& key_system, + const std::string& session_id); + void KeyMessage(const std::string& key_system, + const std::string& session_id, + pp::Buffer_Dev message, + const std::string& default_url); + void KeyError(const std::string& key_system, + const std::string& session_id, + int32_t media_error, + int32_t system_code); + void DeliverBlock(pp::Buffer_Dev decrypted_block, + int32_t request_id); + void DeliverFrame(pp::Buffer_Dev decrypted_frame, + int32_t request_id); + void DeliverSamples(pp::Buffer_Dev decrypted_samples, + int32_t request_id); + + private: + InstanceHandle associated_instance_; +}; + +} // namespace pp + +#endif // PPAPI_CPP_PRIVATE_CONTENT_DECRYPTOR_PRIVATE_H_ diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 735b649..ca15e63 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -124,6 +124,8 @@ 'proxy/ppb_x509_certificate_private_proxy.h', 'proxy/ppp_class_proxy.cc', 'proxy/ppp_class_proxy.h', + 'proxy/ppp_content_decryptor_private_proxy.cc', + 'proxy/ppp_content_decryptor_private_proxy.h', 'proxy/ppp_graphics_3d_proxy.cc', 'proxy/ppp_graphics_3d_proxy.h', 'proxy/ppp_input_event_proxy.cc', @@ -192,6 +194,7 @@ 'proxy/ppb_video_capture_proxy.cc', 'proxy/ppb_video_decoder_proxy.cc', 'proxy/ppb_x509_certificate_private_proxy.cc', + 'proxy/ppp_content_decryptor_private_proxy.cc', 'proxy/ppp_instance_private_proxy.cc', 'proxy/ppp_video_decoder_proxy.cc', 'proxy/serialized_flash_menu.cc', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index 80979ce..1c186b5 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -141,6 +141,7 @@ 'thunk/ppb_buffer_trusted_thunk.cc', 'thunk/ppb_char_set_thunk.cc', 'thunk/ppb_console_thunk.cc', + 'thunk/ppb_content_decryptor_private_thunk.cc', 'thunk/ppb_cursor_control_thunk.cc', 'thunk/ppb_device_ref_api.h', 'thunk/ppb_device_ref_thunk.cc', @@ -263,6 +264,7 @@ 'thunk/ppb_browser_font_trusted_thunk.cc', 'thunk/ppb_buffer_thunk.cc', 'thunk/ppb_buffer_trusted_thunk.cc', + 'thunk/ppb_content_decryptor_private_thunk.cc', 'thunk/ppb_char_set_thunk.cc', 'thunk/ppb_directory_reader_thunk.cc', 'thunk/ppb_file_chooser_thunk.cc', diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi index 563af86..07aae96 100644 --- a/ppapi/ppapi_sources.gypi +++ b/ppapi/ppapi_sources.gypi @@ -91,6 +91,7 @@ # Private interfaces. 'c/private/pp_file_handle.h', + 'c/private/ppb_content_decryptor_private.h', 'c/private/ppb_flash.h', 'c/private/ppb_flash_clipboard.h', 'c/private/ppb_flash_file.h', @@ -113,6 +114,7 @@ 'c/private/ppb_tcp_socket_private.h', 'c/private/ppb_udp_socket_private.h', 'c/private/ppb_x509_certificate_private.h', + 'c/private/ppp_content_decryptor_private.h', # Deprecated interfaces. 'c/dev/deprecated_bool.h', @@ -253,6 +255,8 @@ 'cpp/dev/scriptable_object_deprecated.cc', # Private interfaces. + 'cpp/private/content_decryptor_private.cc', + 'cpp/private/content_decryptor_private.h', 'cpp/private/flash.cc', 'cpp/private/flash.h', 'cpp/private/flash_clipboard.cc', diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index fbd59c3..129901c 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -50,6 +50,7 @@ #include "ppapi/c/ppb_view.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppp_instance.h" +#include "ppapi/c/private/ppb_content_decryptor_private.h" #include "ppapi/c/private/ppb_file_ref_private.h" #include "ppapi/c/private/ppb_flash_clipboard.h" #include "ppapi/c/private/ppb_flash_file.h" @@ -68,6 +69,7 @@ #include "ppapi/c/private/ppb_tcp_socket_private.h" #include "ppapi/c/private/ppb_udp_socket_private.h" #include "ppapi/c/private/ppb_x509_certificate_private.h" +#include "ppapi/c/private/ppp_content_decryptor_private.h" #include "ppapi/c/trusted/ppb_broker_trusted.h" #include "ppapi/c/trusted/ppb_browser_font_trusted.h" #include "ppapi/c/trusted/ppb_char_set_trusted.h" @@ -106,6 +108,7 @@ #include "ppapi/proxy/ppb_video_decoder_proxy.h" #include "ppapi/proxy/ppb_x509_certificate_private_proxy.h" #include "ppapi/proxy/ppp_class_proxy.h" +#include "ppapi/proxy/ppp_content_decryptor_private_proxy.h" #include "ppapi/proxy/ppp_graphics_3d_proxy.h" #include "ppapi/proxy/ppp_input_event_proxy.h" #include "ppapi/proxy/ppp_instance_private_proxy.h" @@ -230,6 +233,14 @@ InterfaceList::InterfaceList() { AddPPB(PPB_Testing_Proxy::GetInfo()); AddPPB(PPB_URLLoader_Proxy::GetTrustedInfo()); AddPPB(PPB_Var_Deprecated_Proxy::GetInfo()); + + // TODO(tomfinegan): Figure out where to put these once we refactor things + // to load the PPP interface struct from the PPB interface. + AddProxy(API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, + &ProxyFactory<PPP_ContentDecryptor_Private_Proxy>); + AddPPP(PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE, + API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, + PPP_ContentDecryptor_Private_Proxy::GetProxyInterface()); #endif // PPP (plugin) interfaces. diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index a72dfd8..ded1fa1 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -245,6 +245,15 @@ IPC_STRUCT_TRAITS_BEGIN(ppapi::NetworkInfo) IPC_STRUCT_TRAITS_MEMBER(display_name) IPC_STRUCT_TRAITS_MEMBER(mtu) IPC_STRUCT_TRAITS_END() + +// TODO(tomfinegan): This is identical to PPPVideoCapture_Buffer, maybe replace +// both with a single type? +IPC_STRUCT_TRAITS_BEGIN(ppapi::proxy::PPPDecryptor_Buffer) + IPC_STRUCT_TRAITS_MEMBER(resource) + IPC_STRUCT_TRAITS_MEMBER(handle) + IPC_STRUCT_TRAITS_MEMBER(size) +IPC_STRUCT_TRAITS_END() + #endif // !defined(OS_NACL) // These are from the browser to the plugin. @@ -575,6 +584,27 @@ IPC_MESSAGE_ROUTED3( IPC::PlatformFileForTransit /* handle */, int32_t /* result */) +// PPP_ContentDecryptor_Dev +IPC_MESSAGE_ROUTED3(PpapiMsg_PPPContentDecryptor_GenerateKeyRequest, + PP_Instance /* instance */, + ppapi::proxy::SerializedVar /* key_system, String */, + ppapi::proxy::SerializedVar /* init_data, ArrayBuffer */) +IPC_MESSAGE_ROUTED3(PpapiMsg_PPPContentDecryptor_AddKey, + PP_Instance /* instance */, + ppapi::proxy::SerializedVar /* session_id, String */, + ppapi::proxy::SerializedVar /* key, ArrayBuffer */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPPContentDecryptor_CancelKeyRequest, + PP_Instance /* instance */, + ppapi::proxy::SerializedVar /* session_id, String */) +IPC_MESSAGE_ROUTED3(PpapiMsg_PPPContentDecryptor_Decrypt, + PP_Instance /* instance */, + ppapi::proxy::PPPDecryptor_Buffer /* buffer */, + int32_t /* request_id */) +IPC_MESSAGE_ROUTED3(PpapiMsg_PPPContentDecryptor_DecryptAndDecode, + PP_Instance /* instance */, + ppapi::HostResource /* encrypted_block, PPB_Buffer_Dev */, + int32_t /* request_id */) + // PPB_NetworkMonitor_Private. IPC_MESSAGE_ROUTED2(PpapiMsg_PPBNetworkMonitor_NetworkList, uint32 /* plugin_dispatcher_id */, @@ -1136,6 +1166,41 @@ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBBuffer_Create, ppapi::HostResource /* result_resource */, base::SharedMemoryHandle /* result_shm_handle */) +// PPB_ContentDecryptor_Dev messages handled in PPB_Instance_Proxy. +IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBInstance_NeedKey, + PP_Instance /* instance */, + ppapi::proxy::SerializedVar /* key_system, String */, + ppapi::proxy::SerializedVar /* session_id, String */, + ppapi::proxy::SerializedVar /* init_data, ArrayBuffer */) +IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBInstance_KeyAdded, + PP_Instance /* instance */, + ppapi::proxy::SerializedVar /* key_system, String */, + ppapi::proxy::SerializedVar /* session_id, String */) +IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBInstance_KeyMessage, + PP_Instance /* instance */, + ppapi::proxy::SerializedVar /* key_system, String */, + ppapi::proxy::SerializedVar /* session_id, String */, + PP_Resource /* message, PPB_Buffer_Dev */, + ppapi::proxy::SerializedVar /* default_url, String */) +IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBInstance_KeyError, + PP_Instance /* instance */, + ppapi::proxy::SerializedVar /* key_system, String */, + ppapi::proxy::SerializedVar /* session_id, String */, + int32_t /* media_error */, + int32_t /* system_code */) +IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBInstance_DeliverBlock, + PP_Instance /* instance */, + PP_Resource /* decrypted_block, PPB_Buffer_Dev */, + int32_t /* request_id */) +IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBInstance_DeliverFrame, + PP_Instance /* instance */, + PP_Resource /* decrypted_frame, PPB_Buffer_Dev */, + int32_t /* request_id */) +IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBInstance_DeliverSamples, + PP_Instance /* instance */, + PP_Resource /* decrypted_samples, PPB_Buffer_Dev */, + int32_t /* request_id */) + // PPB_NetworkMonitor_Private. IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBNetworkMonitor_Start, uint32 /* plugin_dispatcher_id */) diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index ea974ef..698c001 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -136,6 +136,7 @@ bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) { OnHostMsgCancelCompositionText) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_UpdateSurroundingText, OnHostMsgUpdateSurroundingText) + #if !defined(OS_NACL) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_ResolveRelativeToDocument, OnHostMsgResolveRelativeToDocument) @@ -147,6 +148,20 @@ bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) { OnHostMsgGetDocumentURL) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_GetPluginInstanceURL, OnHostMsgGetPluginInstanceURL) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_NeedKey, + OnHostMsgNeedKey) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_KeyAdded, + OnHostMsgKeyAdded) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_KeyMessage, + OnHostMsgKeyMessage) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_KeyError, + OnHostMsgKeyError) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverBlock, + OnHostMsgDeliverBlock) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverFrame, + OnHostMsgDeliverFrame) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverSamples, + OnHostMsgDeliverSamples) #endif // !defined(OS_NACL) // Host -> Plugin messages. @@ -397,6 +412,108 @@ PP_Var PPB_Instance_Proxy::GetPluginInstanceURL( result.Return(dispatcher()), components); } + +void PPB_Instance_Proxy::NeedKey(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Var init_data) { + dispatcher()->Send( + new PpapiHostMsg_PPBInstance_NeedKey( + API_ID_PPB_INSTANCE, + instance, + SerializedVarSendInput(dispatcher(), key_system), + SerializedVarSendInput(dispatcher(), session_id), + SerializedVarSendInput(dispatcher(), init_data))); +} + +void PPB_Instance_Proxy::KeyAdded(PP_Instance instance, + PP_Var key_system, + PP_Var session_id) { + dispatcher()->Send( + new PpapiHostMsg_PPBInstance_KeyAdded( + API_ID_PPB_INSTANCE, + instance, + SerializedVarSendInput(dispatcher(), key_system), + SerializedVarSendInput(dispatcher(), session_id))); +} + +void PPB_Instance_Proxy::KeyMessage(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Resource message, + PP_Var default_url) { + Resource* object = + PpapiGlobals::Get()->GetResourceTracker()->GetResource(message); + if (!object || object->pp_instance() != instance) + return; + dispatcher()->Send( + new PpapiHostMsg_PPBInstance_KeyMessage( + API_ID_PPB_INSTANCE, + instance, + SerializedVarSendInput(dispatcher(), key_system), + SerializedVarSendInput(dispatcher(), session_id), + object->host_resource().host_resource(), + SerializedVarSendInput(dispatcher(), default_url))); +} + +void PPB_Instance_Proxy::KeyError(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + int32_t media_error, + int32_t system_code) { + dispatcher()->Send( + new PpapiHostMsg_PPBInstance_KeyError( + API_ID_PPB_INSTANCE, + instance, + SerializedVarSendInput(dispatcher(), key_system), + SerializedVarSendInput(dispatcher(), session_id), + media_error, + system_code)); +} + +void PPB_Instance_Proxy::DeliverBlock(PP_Instance instance, + PP_Resource decrypted_block, + int32_t request_id) { + Resource* object = + PpapiGlobals::Get()->GetResourceTracker()->GetResource(decrypted_block); + if (!object || object->pp_instance() != instance) + return; + dispatcher()->Send( + new PpapiHostMsg_PPBInstance_DeliverBlock(API_ID_PPB_INSTANCE, + instance, + object->host_resource().host_resource(), + request_id)); +} + +void PPB_Instance_Proxy::DeliverFrame(PP_Instance instance, + PP_Resource decrypted_frame, + int32_t request_id) { + Resource* object = + PpapiGlobals::Get()->GetResourceTracker()->GetResource(decrypted_frame); + if (!object || object->pp_instance() != instance) + return; + dispatcher()->Send(new PpapiHostMsg_PPBInstance_DeliverFrame( + API_ID_PPB_INSTANCE, + instance, + object->host_resource().host_resource(), + request_id)); +} + +void PPB_Instance_Proxy::DeliverSamples(PP_Instance instance, + PP_Resource decrypted_samples, + int32_t request_id) { + Resource* object = + PpapiGlobals::Get()->GetResourceTracker()->GetResource(decrypted_samples); + if (!object || object->pp_instance() != instance) + return; + dispatcher()->Send( + new PpapiHostMsg_PPBInstance_DeliverSamples( + API_ID_PPB_INSTANCE, + instance, + object->host_resource().host_resource(), + request_id)); +} + #endif // !defined(OS_NACL) void PPB_Instance_Proxy::PostMessage(PP_Instance instance, @@ -730,6 +847,88 @@ void PPB_Instance_Proxy::OnHostMsgGetPluginInstanceURL( enter.functions()->GetPluginInstanceURL(instance, NULL)); } } + +void PPB_Instance_Proxy::OnHostMsgNeedKey(PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput session_id, + SerializedVarReceiveInput init_data) { + EnterInstanceNoLock enter(instance); + if (enter.succeeded()) { + enter.functions()->NeedKey(instance, + key_system.Get(dispatcher()), + session_id.Get(dispatcher()), + init_data.Get(dispatcher())); + } +} + +void PPB_Instance_Proxy::OnHostMsgKeyAdded( + PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput session_id) { + EnterInstanceNoLock enter(instance); + if (enter.succeeded()) { + enter.functions()->KeyAdded(instance, + key_system.Get(dispatcher()), + session_id.Get(dispatcher())); + } +} + +void PPB_Instance_Proxy::OnHostMsgKeyMessage( + PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput session_id, + PP_Resource message, + SerializedVarReceiveInput default_url) { + EnterInstanceNoLock enter(instance); + if (enter.succeeded()) { + enter.functions()->KeyMessage(instance, + key_system.Get(dispatcher()), + session_id.Get(dispatcher()), + message, + default_url.Get(dispatcher())); + } +} + +void PPB_Instance_Proxy::OnHostMsgKeyError( + PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput session_id, + int32_t media_error, + int32_t system_error) { + EnterInstanceNoLock enter(instance); + if (enter.succeeded()) { + enter.functions()->KeyError(instance, + key_system.Get(dispatcher()), + session_id.Get(dispatcher()), + media_error, + system_error); + } +} + +void PPB_Instance_Proxy::OnHostMsgDeliverBlock(PP_Instance instance, + PP_Resource decrypted_block, + int32_t request_id) { + EnterInstanceNoLock enter(instance); + if (enter.succeeded()) + enter.functions()->DeliverBlock(instance, decrypted_block, request_id); +} + +void PPB_Instance_Proxy::OnHostMsgDeliverFrame(PP_Instance instance, + PP_Resource decrypted_frame, + int32_t request_id) { + EnterInstanceNoLock enter(instance); + if (enter.succeeded()) + enter.functions()->DeliverFrame(instance, decrypted_frame, request_id); +} + +void PPB_Instance_Proxy::OnHostMsgDeliverSamples(PP_Instance instance, + PP_Resource decrypted_samples, + int32_t request_id) { + EnterInstanceNoLock enter(instance); + if (enter.succeeded()) + enter.functions()->DeliverSamples(instance, decrypted_samples, request_id); +} + #endif // !defined(OS_NACL) void PPB_Instance_Proxy::OnHostMsgSetCursor( diff --git a/ppapi/proxy/ppb_instance_proxy.h b/ppapi/proxy/ppb_instance_proxy.h index e2ac4d7..f7d2905 100644 --- a/ppapi/proxy/ppb_instance_proxy.h +++ b/ppapi/proxy/ppb_instance_proxy.h @@ -115,6 +115,32 @@ class PPB_Instance_Proxy : public InterfaceProxy, virtual PP_Var GetPluginInstanceURL( PP_Instance instance, PP_URLComponents_Dev* components) OVERRIDE; + virtual void NeedKey(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Var init_data) OVERRIDE; + virtual void KeyAdded(PP_Instance instance, + PP_Var key_system, + PP_Var session_id) OVERRIDE; + virtual void KeyMessage(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Resource message, + PP_Var default_url) OVERRIDE; + virtual void KeyError(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + int32_t media_error, + int32_t system_code) OVERRIDE; + virtual void DeliverBlock(PP_Instance instance, + PP_Resource decrypted_block, + int32_t request_id) OVERRIDE; + virtual void DeliverFrame(PP_Instance instance, + PP_Resource decrypted_frame, + int32_t request_id) OVERRIDE; + virtual void DeliverSamples(PP_Instance instance, + PP_Resource decrypted_samples, + int32_t request_id) OVERRIDE; #endif // !defined(OS_NACL) static const ApiID kApiID = API_ID_PPB_INSTANCE; @@ -173,6 +199,7 @@ class PPB_Instance_Proxy : public InterfaceProxy, const std::string& text, uint32_t caret, uint32_t anchor); + #if !defined(OS_NACL) void OnHostMsgResolveRelativeToDocument(PP_Instance instance, SerializedVarReceiveInput relative, @@ -187,6 +214,32 @@ class PPB_Instance_Proxy : public InterfaceProxy, SerializedVarReturnValue result); void OnHostMsgGetPluginInstanceURL(PP_Instance instance, SerializedVarReturnValue result); + virtual void OnHostMsgNeedKey(PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput session_id, + SerializedVarReceiveInput init_data); + virtual void OnHostMsgKeyAdded(PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput session_id); + virtual void OnHostMsgKeyMessage(PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput session_id, + PP_Resource message, + SerializedVarReceiveInput default_url); + virtual void OnHostMsgKeyError(PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput session_id, + int32_t media_error, + int32_t system_code); + virtual void OnHostMsgDeliverBlock(PP_Instance instance, + PP_Resource decrypted_block, + int32_t request_id); + virtual void OnHostMsgDeliverFrame(PP_Instance instance, + PP_Resource decrypted_frame, + int32_t request_id); + virtual void OnHostMsgDeliverSamples(PP_Instance instance, + PP_Resource decrypted_samples, + int32_t request_id); #endif // !defined(OS_NACL) // Host -> Plugin message handlers. 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 0000000..dd72335 --- /dev/null +++ b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc @@ -0,0 +1,311 @@ +// 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/shared_impl/var_tracker.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); +} + +// TODO(dmichael): Refactor so this handle sharing code is in one place. +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)); + #elif defined(OS_POSIX) + handle; + #else + #error Not implemented. + #endif + + *shared_mem_handle = dispatcher->ShareHandleWithRemote(platform_file, false); + return PP_TRUE; +} + +// SerializedVarReceiveInput will decrement the reference count, but we want +// to give the recipient a reference. This utility function takes care of that +// work for the message handlers defined below. +PP_Var ExtractReceivedVarAndAddRef(Dispatcher* dispatcher, + SerializedVarReceiveInput* serialized_var) { + PP_Var var = serialized_var->Get(dispatcher); + PpapiGlobals::Get()->GetVarTracker()->AddRefVar(var); + return var; +} + +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, + ExtractReceivedVarAndAddRef(dispatcher(), &key_system), + ExtractReceivedVarAndAddRef(dispatcher(), &init_data)); + } +} + +void PPP_ContentDecryptor_Private_Proxy::OnMsgAddKey( + PP_Instance instance, + SerializedVarReceiveInput session_id, + SerializedVarReceiveInput key) { + if (ppp_decryptor_impl_) { + CallWhileUnlocked(ppp_decryptor_impl_->AddKey, + instance, + ExtractReceivedVarAndAddRef(dispatcher(), &session_id), + ExtractReceivedVarAndAddRef(dispatcher(), &key)); + } +} + +void PPP_ContentDecryptor_Private_Proxy::OnMsgCancelKeyRequest( + PP_Instance instance, + SerializedVarReceiveInput session_id) { + if (ppp_decryptor_impl_) { + CallWhileUnlocked(ppp_decryptor_impl_->CancelKeyRequest, + instance, + ExtractReceivedVarAndAddRef(dispatcher(), &session_id)); + } +} + +void PPP_ContentDecryptor_Private_Proxy::OnMsgDecrypt( + PP_Instance instance, + const 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 diff --git a/ppapi/proxy/ppp_content_decryptor_private_proxy.h b/ppapi/proxy/ppp_content_decryptor_private_proxy.h new file mode 100644 index 0000000..6ed8d22 --- /dev/null +++ b/ppapi/proxy/ppp_content_decryptor_private_proxy.h @@ -0,0 +1,54 @@ +// 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. + +#ifndef PPAPI_PROXY_PPP_CONTENT_DECRYPTOR_PRIVATE_PROXY_H_ +#define PPAPI_PROXY_PPP_CONTENT_DECRYPTOR_PRIVATE_PROXY_H_ + +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/private/ppp_content_decryptor_private.h" +#include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/serialized_structs.h" +#include "ppapi/shared_impl/host_resource.h" + +namespace ppapi { +namespace proxy { + +class SerializedVarReceiveInput; + +class PPP_ContentDecryptor_Private_Proxy : public InterfaceProxy { + public: + explicit PPP_ContentDecryptor_Private_Proxy(Dispatcher* dispatcher); + virtual ~PPP_ContentDecryptor_Private_Proxy(); + + static const PPP_ContentDecryptor_Private* GetProxyInterface(); + + private: + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + // Message handlers. + void OnMsgGenerateKeyRequest(PP_Instance instance, + SerializedVarReceiveInput key_system, + SerializedVarReceiveInput init_data); + void OnMsgAddKey(PP_Instance instance, + SerializedVarReceiveInput session_id, + SerializedVarReceiveInput key); + void OnMsgCancelKeyRequest(PP_Instance instance, + SerializedVarReceiveInput session_id); + void OnMsgDecrypt(PP_Instance instance, + const PPPDecryptor_Buffer& encrypted_buffer, + int32_t request_id); + void OnMsgDecryptAndDecode(PP_Instance instance, + const HostResource& encrypted_block, + int32_t request_id); + + const PPP_ContentDecryptor_Private* ppp_decryptor_impl_; + + DISALLOW_COPY_AND_ASSIGN(PPP_ContentDecryptor_Private_Proxy); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_PPP_CONTENT_DECRYPTOR_PRIVATE_PROXY_H_ diff --git a/ppapi/proxy/serialized_structs.h b/ppapi/proxy/serialized_structs.h index 6bb0da0..3174449 100644 --- a/ppapi/proxy/serialized_structs.h +++ b/ppapi/proxy/serialized_structs.h @@ -101,6 +101,14 @@ struct PPPVideoCapture_Buffer { base::SharedMemoryHandle handle; }; +// TODO(tomfinegan): This is identical to PPPVideoCapture_Buffer, maybe replace +// both with a single type? +struct PPPDecryptor_Buffer { + ppapi::HostResource resource; + uint32_t size; + base::SharedMemoryHandle handle; +}; + #if defined(OS_WIN) typedef HANDLE ImageHandle; #elif defined(OS_MACOSX) || defined(OS_ANDROID) diff --git a/ppapi/shared_impl/api_id.h b/ppapi/shared_impl/api_id.h index 83fbf5a..ba1723c 100644 --- a/ppapi/shared_impl/api_id.h +++ b/ppapi/shared_impl/api_id.h @@ -54,6 +54,9 @@ enum ApiID { API_ID_PPB_X509_CERTIFICATE_PRIVATE, API_ID_PPP_CLASS, + // TODO(tomfinegan): Remove this after we refactor things to load the PPP + // interface struct from the PPB interface. + API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, API_ID_PPP_GRAPHICS_3D, API_ID_PPP_INPUT_EVENT, API_ID_PPP_INSTANCE, diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h index 4a170f4..0237f18 100644 --- a/ppapi/tests/all_c_includes.h +++ b/ppapi/tests/all_c_includes.h @@ -92,6 +92,7 @@ #include "ppapi/c/ppp_instance.h" #include "ppapi/c/ppp_messaging.h" #include "ppapi/c/ppp_mouse_lock.h" +#include "ppapi/c/private/ppb_content_decryptor_private.h" #include "ppapi/c/private/ppb_flash.h" #include "ppapi/c/private/ppb_flash_clipboard.h" #include "ppapi/c/private/ppb_flash_menu.h" @@ -110,6 +111,7 @@ #include "ppapi/c/private/ppb_uma_private.h" #include "ppapi/c/private/ppb_x509_certificate_private.h" #include "ppapi/c/private/ppp_instance_private.h" +#include "ppapi/c/private/ppp_content_decryptor_private.h" #include "ppapi/c/trusted/ppb_audio_trusted.h" #include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/c/trusted/ppb_graphics_3d_trusted.h" diff --git a/ppapi/tests/all_cpp_includes.h b/ppapi/tests/all_cpp_includes.h index 08700cc..1013171 100644 --- a/ppapi/tests/all_cpp_includes.h +++ b/ppapi/tests/all_cpp_includes.h @@ -48,6 +48,7 @@ #include "ppapi/cpp/module_impl.h" #include "ppapi/cpp/mouse_lock.h" #include "ppapi/cpp/point.h" +#include "ppapi/cpp/private/content_decryptor_private.h" #include "ppapi/cpp/private/flash_fullscreen.h" #include "ppapi/cpp/private/instance_private.h" #include "ppapi/cpp/private/instance_private.h" diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h index 50d3ea4..144d64c 100644 --- a/ppapi/thunk/interfaces_ppb_private.h +++ b/ppapi/thunk/interfaces_ppb_private.h @@ -21,6 +21,9 @@ PROXIED_IFACE(PPB_Broker, PPB_BROKER_TRUSTED_INTERFACE_0_2, PPB_BrokerTrusted_0_2) PROXIED_IFACE(PPB_Instance, PPB_BROWSERFONT_TRUSTED_INTERFACE_1_0, PPB_BrowserFont_Trusted_1_0) +PROXIED_IFACE(PPB_Instance, + PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_1, + PPB_ContentDecryptor_Private_0_1) PROXIED_IFACE(PPB_Instance, PPB_CHARSET_TRUSTED_INTERFACE_1_0, PPB_CharSet_Trusted_1_0) PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_5, diff --git a/ppapi/thunk/ppb_content_decryptor_private_thunk.cc b/ppapi/thunk/ppb_content_decryptor_private_thunk.cc new file mode 100644 index 0000000..e96a990 --- /dev/null +++ b/ppapi/thunk/ppb_content_decryptor_private_thunk.cc @@ -0,0 +1,98 @@ +// 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/c/private/ppb_content_decryptor_private.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_instance_api.h" +#include "ppapi/thunk/thunk.h" + +namespace ppapi { +namespace thunk { + +namespace { + +void NeedKey(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Var init_data) { + EnterInstance enter(instance); + if (enter.succeeded()) + enter.functions()->NeedKey(instance, key_system, session_id, init_data); +} + +void KeyAdded(PP_Instance instance, + PP_Var key_system, + PP_Var session_id) { + EnterInstance enter(instance); + if (enter.succeeded()) + enter.functions()->KeyAdded(instance, key_system, session_id); +} + +void KeyMessage(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Resource message, + PP_Var default_url) { + EnterInstance enter(instance); + if (enter.succeeded()) { + enter.functions()->KeyMessage(instance, key_system, session_id, message, + default_url); + } +} + +void KeyError(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + int32_t media_error, + int32_t system_code) { + EnterInstance enter(instance); + if (enter.succeeded()) { + enter.functions()->KeyError(instance, key_system, session_id, media_error, + system_code); + } +} + +void DeliverBlock(PP_Instance instance, + PP_Resource decrypted_block, + int32_t request_id) { + EnterInstance enter(instance); + if (enter.succeeded()) + enter.functions()->DeliverBlock(instance, decrypted_block, request_id); +} + +void DeliverFrame(PP_Instance instance, + PP_Resource decrypted_frame, + int32_t request_id) { + EnterInstance enter(instance); + if (enter.succeeded()) + enter.functions()->DeliverFrame(instance, decrypted_frame, request_id); +} + +void DeliverSamples(PP_Instance instance, + PP_Resource decrypted_samples, + int32_t request_id) { + EnterInstance enter(instance); + if (enter.succeeded()) + enter.functions()->DeliverSamples(instance, decrypted_samples, request_id); +} + +const PPB_ContentDecryptor_Private g_ppb_decryption_thunk = { + &NeedKey, + &KeyAdded, + &KeyMessage, + &KeyError, + &DeliverBlock, + &DeliverFrame, + &DeliverSamples +}; + +} // namespace + +const PPB_ContentDecryptor_Private* + GetPPB_ContentDecryptor_Private_0_1_Thunk() { + return &g_ppb_decryption_thunk; +} + +} // namespace thunk +} // namespace ppapi diff --git a/ppapi/thunk/ppb_instance_api.h b/ppapi/thunk/ppb_instance_api.h index 9b4e644..1520e13 100644 --- a/ppapi/thunk/ppb_instance_api.h +++ b/ppapi/thunk/ppb_instance_api.h @@ -139,6 +139,34 @@ class PPB_Instance_API { double minimum_factor, double maximium_factor) = 0; #if !defined(OS_NACL) + // Content Decryptor. + virtual void NeedKey(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Var init_data) = 0; + virtual void KeyAdded(PP_Instance instance, + PP_Var key_system, + PP_Var session_id) = 0; + virtual void KeyMessage(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Resource message, + PP_Var default_url) = 0; + virtual void KeyError(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + int32_t media_error, + int32_t system_error) = 0; + virtual void DeliverBlock(PP_Instance instance, + PP_Resource decrypted_block, + int32_t request_id) = 0; + virtual void DeliverFrame(PP_Instance instance, + PP_Resource decrypted_frame, + int32_t request_id) = 0; + virtual void DeliverSamples(PP_Instance instance, + PP_Resource decrypted_samples, + int32_t request_id) = 0; + // URLUtil. virtual PP_Var ResolveRelativeToDocument( PP_Instance instance, diff --git a/webkit/media/crypto/ppapi/DEPS b/webkit/media/crypto/ppapi/DEPS new file mode 100644 index 0000000..bfb45fe --- /dev/null +++ b/webkit/media/crypto/ppapi/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+ppapi", +] diff --git a/webkit/media/crypto/ppapi/cdm_wrapper.cc b/webkit/media/crypto/ppapi/cdm_wrapper.cc new file mode 100644 index 0000000..8b7edf3 --- /dev/null +++ b/webkit/media/crypto/ppapi/cdm_wrapper.cc @@ -0,0 +1,228 @@ +// 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 <cstring> // For std::memcpy. + +#include "base/compiler_specific.h" // For OVERRIDE. +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/core.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/logging.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/pass_ref.h" +#include "ppapi/cpp/resource.h" +#include "ppapi/cpp/var.h" +#include "ppapi/cpp/var_array_buffer.h" +#include "ppapi/cpp/dev/buffer_dev.h" +#include "ppapi/cpp/private/content_decryptor_private.h" +#include "ppapi/utility/completion_callback_factory.h" + +namespace { + +struct DecryptorMessage { + DecryptorMessage() : media_error(0), system_code(0) {} + std::string key_system; + std::string session_id; + std::string default_url; + std::string message_data; + int32_t media_error; + int32_t system_code; +}; + +struct DecryptedBlock { + DecryptedBlock() : request_id(0) {} + int32_t request_id; + std::string data; +}; + +void CallOnMain(pp::CompletionCallback cb) { + pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); +} + +} // namespace + + +// A wrapper class for abstracting away PPAPI interaction and threading for a +// Content Decryption Module (CDM). +class CDMWrapper : public pp::Instance, + public pp::ContentDecryptor_Private { + public: + CDMWrapper(PP_Instance instance, pp::Module* module); + virtual ~CDMWrapper() {} + + // PPP_ContentDecryptor_Private methods + virtual bool GenerateKeyRequest(const std::string& key_system, + pp::VarArrayBuffer init_data) OVERRIDE; + virtual bool AddKey(const std::string& session_id, + pp::VarArrayBuffer key) OVERRIDE; + virtual bool CancelKeyRequest(const std::string& session_id) OVERRIDE; + virtual bool Decrypt(pp::Buffer_Dev encrypted_buffer, + int32_t request_id) OVERRIDE; + + virtual bool DecryptAndDecode(pp::Buffer_Dev encrypted_buffer, + int32_t request_id) OVERRIDE { + return false; + } + + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { + return true; + } + + private: + PP_Resource StringToBufferResource(const std::string& str); + + // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to + // <code>callback_factory_</code> to ensure that calls into + // <code>PPP_ContentDecryptor_Private</code> are asynchronous. + void NeedKey(int32_t result, const DecryptorMessage& decryptor_message); + void KeyAdded(int32_t result, const DecryptorMessage& decryptor_message); + void KeyMessage(int32_t result, const DecryptorMessage& decryptor_message); + void KeyError(int32_t result, const DecryptorMessage& decryptor_message); + void DeliverBlock(int32_t result, const DecryptedBlock& decrypted_block); + + pp::CompletionCallbackFactory<CDMWrapper> callback_factory_; +}; + +CDMWrapper::CDMWrapper(PP_Instance instance, + pp::Module* module) + : pp::Instance(instance), + pp::ContentDecryptor_Private(this) { + callback_factory_.Initialize(this); +} + +bool CDMWrapper::GenerateKeyRequest(const std::string& key_system, + pp::VarArrayBuffer init_data) { + PP_DCHECK(!key_system.empty() && init_data.ByteLength()); + + DecryptorMessage decryptor_message; + decryptor_message.key_system = key_system; + decryptor_message.session_id = "0"; + decryptor_message.default_url = "http://www.google.com"; + decryptor_message.message_data = "GenerateKeyRequest"; + + CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage, + decryptor_message)); + return true; +} + +bool CDMWrapper::AddKey(const std::string& session_id, + pp::VarArrayBuffer key) { + const std::string key_string(reinterpret_cast<char*>(key.Map()), + key.ByteLength()); + + PP_DCHECK(!session_id.empty() && !key_string.empty()); + + DecryptorMessage decryptor_message; + decryptor_message.key_system = "AddKey"; + decryptor_message.session_id = "0"; + decryptor_message.default_url = "http://www.google.com"; + decryptor_message.message_data = "AddKey"; + CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyAdded, + decryptor_message)); + return true; +} + +bool CDMWrapper::CancelKeyRequest(const std::string& session_id) { + // TODO(tomfinegan): cancel pending key request in CDM. + + PP_DCHECK(!session_id.empty()); + + DecryptorMessage decryptor_message; + decryptor_message.key_system = "CancelKeyRequest"; + decryptor_message.session_id = "0"; + decryptor_message.default_url = "http://www.google.com"; + decryptor_message.message_data = "CancelKeyRequest"; + CallOnMain(callback_factory_.NewCallback(&CDMWrapper::KeyMessage, + decryptor_message)); + return true; +} + +bool CDMWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer, + int32_t request_id) { + PP_DCHECK(!encrypted_buffer.is_null()); + + DecryptedBlock decrypted_block; + decrypted_block.request_id = request_id; + decrypted_block.data = "Pretend I'm decrypted data!"; + CallOnMain(callback_factory_.NewCallback(&CDMWrapper::DeliverBlock, + decrypted_block)); + return true; +} + +PP_Resource CDMWrapper::StringToBufferResource(const std::string& str) { + if (str.empty()) + return 0; + + pp::Buffer_Dev buffer(this, str.size()); + if (!buffer.data()) + return 0; + + std::memcpy(buffer.data(), str.data(), str.size()); + return buffer.detach(); +} + +void CDMWrapper::NeedKey(int32_t result, + const DecryptorMessage& decryptor_message) { + const std::string& message_data = decryptor_message.message_data; + pp::VarArrayBuffer init_data(message_data.size()); + std::memcpy(init_data.Map(), message_data.data(), message_data.size()); + pp::ContentDecryptor_Private::NeedKey(decryptor_message.key_system, + decryptor_message.session_id, + init_data); +} + +void CDMWrapper::KeyAdded(int32_t result, + const DecryptorMessage& decryptor_message) { + pp::ContentDecryptor_Private::KeyAdded(decryptor_message.key_system, + decryptor_message.session_id); +} + +void CDMWrapper::KeyMessage(int32_t result, + const DecryptorMessage& decryptor_message) { + pp::Buffer_Dev message_buffer( + StringToBufferResource(decryptor_message.message_data)); + pp::ContentDecryptor_Private::KeyMessage(decryptor_message.key_system, + decryptor_message.session_id, + message_buffer, + decryptor_message.default_url); +} + +void CDMWrapper::KeyError(int32_t result, + const DecryptorMessage& decryptor_message) { + pp::ContentDecryptor_Private::KeyError(decryptor_message.key_system, + decryptor_message.session_id, + decryptor_message.media_error, + decryptor_message.system_code); +} + +void CDMWrapper::DeliverBlock(int32_t result, + const DecryptedBlock& decrypted_block) { + pp::Buffer_Dev decrypted_buffer( + StringToBufferResource(decrypted_block.data)); + pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer, + decrypted_block.request_id); +} + +// This object is the global object representing this plugin library as long +// as it is loaded. +class MyModule : public pp::Module { + public: + MyModule() : pp::Module() {} + virtual ~MyModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new CDMWrapper(instance, this); + } +}; + +namespace pp { + +// Factory function for your specialization of the Module object. +Module* CreateModule() { + return new MyModule(); +} + +} // namespace pp diff --git a/webkit/media/webkit_media.gypi b/webkit/media/webkit_media.gypi index d152991..834ba48 100644 --- a/webkit/media/webkit_media.gypi +++ b/webkit/media/webkit_media.gypi @@ -83,5 +83,39 @@ }], ], }, + { + 'target_name': 'ppapi_cdm_wrapper', + 'type': 'none', + 'dependencies': [ + '<(DEPTH)/ppapi/ppapi.gyp:ppapi_cpp' + ], + 'conditions': [ + ['os_posix==1 and OS!="mac"', { + 'cflags': ['-fvisibility=hidden'], + 'type': 'shared_library', + # -gstabs, used in the official builds, causes an ICE. Simply remove + # it. + 'cflags!': ['-gstabs'], + }], + ['OS=="win"', { + 'type': 'shared_library', + }], + ['OS=="mac"', { + 'type': 'loadable_module', + 'mac_bundle': 1, + 'product_extension': 'plugin', + 'xcode_settings': { + 'OTHER_LDFLAGS': [ + # Not to strip important symbols by -Wl,-dead_strip. + '-Wl,-exported_symbol,_PPP_GetInterface', + '-Wl,-exported_symbol,_PPP_InitializeModule', + '-Wl,-exported_symbol,_PPP_ShutdownModule' + ]}, + }], + ], + 'sources': [ + 'crypto/ppapi/cdm_wrapper.cc', + ], + } ], } diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc index 96694f6..0af8dc1 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc @@ -114,6 +114,7 @@ using ppapi::thunk::PPB_Graphics2D_API; using ppapi::thunk::PPB_Graphics3D_API; using ppapi::thunk::PPB_ImageData_API; using ppapi::Var; +using ppapi::ArrayBufferVar; using ppapi::ViewData; using WebKit::WebBindings; using WebKit::WebCanvas; @@ -294,6 +295,29 @@ scoped_array<const char*> StringVectorToArgArray( return array.Pass(); } +// Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the +// buffer resource, and returns it. Returns a an invalid PP_Resource with an ID +// of 0 on failure. Upon success, the returned Buffer resource has a reference +// count of 1. +PP_Resource MakeBufferResource(PP_Instance instance, + const base::StringPiece& data) { + if (data.empty()) + return 0; + + ScopedPPResource resource(PPB_Buffer_Impl::Create(instance, data.size())); + if (!resource.get()) + return 0; + + EnterResourceNoLock<PPB_Buffer_API> enter(resource, true); + if (enter.failed()) + return 0; + + BufferAutoMapper mapper(enter.object()); + memcpy(mapper.data(), data.data(), data.size()); + + return resource.get(); +} + } // namespace // static @@ -323,6 +347,7 @@ PluginInstance::PluginInstance( has_webkit_focus_(false), has_content_area_focus_(false), find_identifier_(-1), + plugin_decryption_interface_(NULL), plugin_find_interface_(NULL), plugin_input_event_interface_(NULL), plugin_messaging_interface_(NULL), @@ -965,6 +990,16 @@ void PluginInstance::StopFind() { plugin_find_interface_->StopFind(pp_instance()); } +bool PluginInstance::LoadContentDecryptorInterface() { + if (!plugin_decryption_interface_) { + plugin_decryption_interface_ = + static_cast<const PPP_ContentDecryptor_Private*>( + module_->GetPluginInterface( + PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE)); + } + return !!plugin_decryption_interface_; +} + bool PluginInstance::LoadFindInterface() { if (!plugin_find_interface_) { plugin_find_interface_ = @@ -1282,6 +1317,75 @@ void PluginInstance::RotateView(WebPlugin::RotationType type) { // NOTE: plugin instance may have been deleted. } +bool PluginInstance::GenerateKeyRequest(const std::string& key_system, + const std::string& init_data) { + if (!LoadContentDecryptorInterface()) + return false; + if (key_system.empty()) + return false; + PP_Var init_data_array = + PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( + init_data.size(), init_data.data()); + + return PP_ToBool(plugin_decryption_interface_->GenerateKeyRequest( + pp_instance(), + StringVar::StringToPPVar(key_system), + init_data_array)); +} + +bool PluginInstance::AddKey(const std::string& session_id, + const std::string& key) { + if (!LoadContentDecryptorInterface()) + return false; + PP_Var key_array = + PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(key.size(), + key.data()); + + return PP_ToBool(plugin_decryption_interface_->AddKey( + pp_instance(), + StringVar::StringToPPVar(session_id), + key_array)); +} + +bool PluginInstance::CancelKeyRequest(const std::string& session_id) { + if (!LoadContentDecryptorInterface()) + return false; + + return PP_ToBool(plugin_decryption_interface_->CancelKeyRequest( + pp_instance(), + StringVar::StringToPPVar(session_id))); +} + +bool PluginInstance::Decrypt(const base::StringPiece& encrypted_block, + const DecryptedDataCB& callback) { + if (!LoadContentDecryptorInterface()) + return false; + ScopedPPResource encrypted_resource(MakeBufferResource(pp_instance(), + encrypted_block)); + if (!encrypted_resource.get()) + return false; + + // TODO(tomfinegan): Store callback and ID in a map, and pass ID to decryptor. + return PP_ToBool(plugin_decryption_interface_->Decrypt(pp_instance(), + encrypted_resource, + 0)); +} + +bool PluginInstance::DecryptAndDecode(const base::StringPiece& encrypted_block, + const DecryptedDataCB& callback) { + if (!LoadContentDecryptorInterface()) + return false; + ScopedPPResource encrypted_resource(MakeBufferResource(pp_instance(), + encrypted_block)); + if (!encrypted_resource.get()) + return false; + // TODO(tomfinegan): Store callback and ID in a map, and pass ID to decryptor. + return PP_ToBool(plugin_decryption_interface_->DecryptAndDecode( + pp_instance(), + encrypted_resource, + 0)); +} + bool PluginInstance::FlashIsFullscreenOrPending() { return fullscreen_container_ != NULL; } @@ -1890,6 +1994,56 @@ PP_Var PluginInstance::GetFontFamilies(PP_Instance instance) { return PP_MakeUndefined(); } +void PluginInstance::NeedKey(PP_Instance instance, + PP_Var key_system_var, + PP_Var session_id_var, + PP_Var init_data_var) { + // TODO(tomfinegan): send the data to media stack. +} + +void PluginInstance::KeyAdded(PP_Instance instance, + PP_Var key_system_var, + PP_Var session_id_var) { + // TODO(tomfinegan): send the data to media stack. +} + +void PluginInstance::KeyMessage(PP_Instance instance, + PP_Var key_system_var, + PP_Var session_id_var, + PP_Resource message_resource, + PP_Var default_url_var) { + // TODO(tomfinegan): send the data to media stack. +} + +void PluginInstance::KeyError(PP_Instance instance, + PP_Var key_system_var, + PP_Var session_id_var, + int32_t media_error, + int32_t system_code) { + // TODO(tomfinegan): send the data to media stack. +} + +void PluginInstance::DeliverBlock(PP_Instance instance, + PP_Resource decrypted_block, + int32_t request_id) { + // TODO(xhwang): Pass the decrypted block back to media stack. +} + +void PluginInstance::DeliverFrame(PP_Instance instance, + PP_Resource decrypted_frame, + int32_t request_id) { + // TODO(tomfinegan): To be implemented after completion of v0.1 of the + // EME/CDM work. +} + +void PluginInstance::DeliverSamples(PP_Instance instance, + PP_Resource decrypted_samples, + int32_t request_id) { + // TODO(tomfinegan): To be implemented after completion of v0.1 of the + // EME/CDM work. +} + + void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, int32_t total, PP_Bool final_result) { diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.h b/webkit/plugins/ppapi/ppapi_plugin_instance.h index 24eb715..1d00b3c 100644 --- a/webkit/plugins/ppapi/ppapi_plugin_instance.h +++ b/webkit/plugins/ppapi/ppapi_plugin_instance.h @@ -10,6 +10,7 @@ #include <vector> #include "base/basictypes.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" @@ -34,6 +35,8 @@ #include "ppapi/c/ppp_input_event.h" #include "ppapi/c/ppp_messaging.h" #include "ppapi/c/ppp_mouse_lock.h" +#include "ppapi/c/private/ppb_content_decryptor_private.h" +#include "ppapi/c/private/ppp_content_decryptor_private.h" #include "ppapi/c/private/ppp_instance_private.h" #include "ppapi/shared_impl/ppb_instance_shared.h" #include "ppapi/shared_impl/ppb_view_shared.h" @@ -236,6 +239,19 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : void Graphics3DContextLost(); + // Provides access to PPP_ContentDecryptor_Private. + // TODO(tomfinegan): Move decryptor methods to delegate class. + typedef base::Callback<void(void*, int)> DecryptedDataCB; + bool GenerateKeyRequest(const std::string& key_system, + const std::string& init_data); + bool AddKey(const std::string& session_id, + const std::string& key); + bool CancelKeyRequest(const std::string& session_id); + bool Decrypt(const base::StringPiece& encypted_block, + const DecryptedDataCB& callback); + bool DecryptAndDecode(const base::StringPiece& encypted_block, + const DecryptedDataCB& callback); + // There are 2 implementations of the fullscreen interface // PPB_FlashFullscreen is used by Pepper Flash. // PPB_Fullscreen is intended for other applications including NaCl. @@ -409,6 +425,34 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : PP_Instance instance, PP_URLComponents_Dev* components) OVERRIDE; + // TODO(tomfinegan): Move the next 7 methods to a delegate class. + virtual void NeedKey(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Var init_data) OVERRIDE; + virtual void KeyAdded(PP_Instance instance, + PP_Var key_system, + PP_Var session_id) OVERRIDE; + virtual void KeyMessage(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + PP_Resource message, + PP_Var default_url) OVERRIDE; + virtual void KeyError(PP_Instance instance, + PP_Var key_system, + PP_Var session_id, + int32_t media_error, + int32_t system_code) OVERRIDE; + virtual void DeliverBlock(PP_Instance instance, + PP_Resource decrypted_block, + int32_t request_id) OVERRIDE; + virtual void DeliverFrame(PP_Instance instance, + PP_Resource decrypted_frame, + int32_t request_id) OVERRIDE; + virtual void DeliverSamples(PP_Instance instance, + PP_Resource decrypted_samples, + int32_t request_id) OVERRIDE; + // Reset this instance as proxied. Resets cached interfaces to point to the // proxy and re-sends DidCreate, DidChangeView, and HandleDocumentLoad (if // necessary). @@ -424,6 +468,7 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : PluginModule* module, ::ppapi::PPP_Instance_Combined* instance_interface); + bool LoadContentDecryptorInterface(); bool LoadFindInterface(); bool LoadInputEventInterface(); bool LoadMessagingInterface(); @@ -555,6 +600,7 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance : scoped_ptr< ::ppapi::thunk::ResourceCreationAPI> resource_creation_; // The plugin-provided interfaces. + const PPP_ContentDecryptor_Private* plugin_decryption_interface_; const PPP_Find_Dev* plugin_find_interface_; const PPP_InputEvent* plugin_input_event_interface_; const PPP_Messaging* plugin_messaging_interface_; |