summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ppapi/cpp/private/content_decryptor_private.cc239
-rw-r--r--ppapi/cpp/private/content_decryptor_private.h68
-rw-r--r--ppapi/ppapi_proxy.gypi3
-rw-r--r--ppapi/ppapi_shared.gypi2
-rw-r--r--ppapi/ppapi_sources.gypi4
-rw-r--r--ppapi/proxy/interface_list.cc11
-rw-r--r--ppapi/proxy/ppapi_messages.h65
-rw-r--r--ppapi/proxy/ppb_instance_proxy.cc199
-rw-r--r--ppapi/proxy/ppb_instance_proxy.h53
-rw-r--r--ppapi/proxy/ppp_content_decryptor_private_proxy.cc311
-rw-r--r--ppapi/proxy/ppp_content_decryptor_private_proxy.h54
-rw-r--r--ppapi/proxy/serialized_structs.h8
-rw-r--r--ppapi/shared_impl/api_id.h3
-rw-r--r--ppapi/tests/all_c_includes.h2
-rw-r--r--ppapi/tests/all_cpp_includes.h1
-rw-r--r--ppapi/thunk/interfaces_ppb_private.h3
-rw-r--r--ppapi/thunk/ppb_content_decryptor_private_thunk.cc98
-rw-r--r--ppapi/thunk/ppb_instance_api.h28
-rw-r--r--webkit/media/crypto/ppapi/DEPS3
-rw-r--r--webkit/media/crypto/ppapi/cdm_wrapper.cc228
-rw-r--r--webkit/media/webkit_media.gypi34
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.cc154
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.h46
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_;