1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ppapi/cpp/private/content_decryptor_private.h" 6 7#include <cstring> // memcpy 8 9#include "ppapi/c/ppb_var.h" 10#include "ppapi/c/private/ppb_content_decryptor_private.h" 11#include "ppapi/c/private/ppp_content_decryptor_private.h" 12#include "ppapi/cpp/instance.h" 13#include "ppapi/cpp/instance_handle.h" 14#include "ppapi/cpp/logging.h" 15#include "ppapi/cpp/module.h" 16#include "ppapi/cpp/module_impl.h" 17#include "ppapi/cpp/var.h" 18 19namespace pp { 20 21namespace { 22 23static const char kPPPContentDecryptorInterface[] = 24 PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 25 26void GenerateKeyRequest(PP_Instance instance, 27 PP_Var key_system_arg, 28 PP_Var type_arg, 29 PP_Var init_data_arg) { 30 void* object = 31 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 32 if (!object) 33 return; 34 35 pp::Var key_system_var(pp::PASS_REF, key_system_arg); 36 if (!key_system_var.is_string()) 37 return; 38 39 pp::Var type_var(pp::PASS_REF, type_arg); 40 if (!type_var.is_string()) 41 return; 42 43 pp::Var init_data_var(pp::PASS_REF, init_data_arg); 44 if (!init_data_var.is_array_buffer()) 45 return; 46 pp::VarArrayBuffer init_data_array_buffer(init_data_var); 47 48 static_cast<ContentDecryptor_Private*>(object)->GenerateKeyRequest( 49 key_system_var.AsString(), 50 type_var.AsString(), 51 init_data_array_buffer); 52} 53 54void AddKey(PP_Instance instance, 55 PP_Var session_id_arg, 56 PP_Var key_arg, 57 PP_Var init_data_arg) { 58 void* object = 59 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 60 if (!object) 61 return; 62 63 pp::Var session_id_var(pp::PASS_REF, session_id_arg); 64 if (!session_id_var.is_string()) 65 return; 66 67 pp::Var key_var(pp::PASS_REF, key_arg); 68 if (!key_var.is_array_buffer()) 69 return; 70 pp::VarArrayBuffer key(key_var); 71 72 pp::Var init_data_var(pp::PASS_REF, init_data_arg); 73 if (!init_data_var.is_array_buffer()) 74 return; 75 pp::VarArrayBuffer init_data(init_data_var); 76 77 78 static_cast<ContentDecryptor_Private*>(object)->AddKey( 79 session_id_var.AsString(), 80 key, 81 init_data); 82} 83 84void CancelKeyRequest(PP_Instance instance, PP_Var session_id_arg) { 85 void* object = 86 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 87 if (!object) 88 return; 89 90 pp::Var session_id_var(pp::PASS_REF, session_id_arg); 91 if (!session_id_var.is_string()) 92 return; 93 94 static_cast<ContentDecryptor_Private*>(object)->CancelKeyRequest( 95 session_id_var.AsString()); 96} 97 98 99void Decrypt(PP_Instance instance, 100 PP_Resource encrypted_resource, 101 const PP_EncryptedBlockInfo* encrypted_block_info) { 102 pp::Buffer_Dev encrypted_block(encrypted_resource); 103 104 void* object = 105 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 106 if (!object) 107 return; 108 109 static_cast<ContentDecryptor_Private*>(object)->Decrypt( 110 encrypted_block, 111 *encrypted_block_info); 112} 113 114void InitializeAudioDecoder( 115 PP_Instance instance, 116 const PP_AudioDecoderConfig* decoder_config, 117 PP_Resource extra_data_resource) { 118 pp::Buffer_Dev extra_data_buffer(extra_data_resource); 119 120 void* object = 121 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 122 if (!object) 123 return; 124 125 static_cast<ContentDecryptor_Private*>(object)->InitializeAudioDecoder( 126 *decoder_config, 127 extra_data_buffer); 128} 129 130void InitializeVideoDecoder( 131 PP_Instance instance, 132 const PP_VideoDecoderConfig* decoder_config, 133 PP_Resource extra_data_resource) { 134 pp::Buffer_Dev extra_data_buffer(extra_data_resource); 135 136 void* object = 137 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 138 if (!object) 139 return; 140 141 static_cast<ContentDecryptor_Private*>(object)->InitializeVideoDecoder( 142 *decoder_config, 143 extra_data_buffer); 144} 145 146void DeinitializeDecoder(PP_Instance instance, 147 PP_DecryptorStreamType decoder_type, 148 uint32_t request_id) { 149 void* object = 150 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 151 if (!object) 152 return; 153 static_cast<ContentDecryptor_Private*>(object)->DeinitializeDecoder( 154 decoder_type, 155 request_id); 156} 157 158void ResetDecoder(PP_Instance instance, 159 PP_DecryptorStreamType decoder_type, 160 uint32_t request_id) { 161 void* object = 162 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 163 if (!object) 164 return; 165 static_cast<ContentDecryptor_Private*>(object)->ResetDecoder(decoder_type, 166 request_id); 167} 168 169void DecryptAndDecode(PP_Instance instance, 170 PP_DecryptorStreamType decoder_type, 171 PP_Resource encrypted_resource, 172 const PP_EncryptedBlockInfo* encrypted_block_info) { 173 pp::Buffer_Dev encrypted_buffer(encrypted_resource); 174 175 void* object = 176 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 177 if (!object) 178 return; 179 180 static_cast<ContentDecryptor_Private*>(object)->DecryptAndDecode( 181 decoder_type, 182 encrypted_buffer, 183 *encrypted_block_info); 184} 185 186const PPP_ContentDecryptor_Private ppp_content_decryptor = { 187 &GenerateKeyRequest, 188 &AddKey, 189 &CancelKeyRequest, 190 &Decrypt, 191 &InitializeAudioDecoder, 192 &InitializeVideoDecoder, 193 &DeinitializeDecoder, 194 &ResetDecoder, 195 &DecryptAndDecode 196}; 197 198template <> const char* interface_name<PPB_ContentDecryptor_Private>() { 199 return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 200} 201 202} // namespace 203 204ContentDecryptor_Private::ContentDecryptor_Private(Instance* instance) 205 : associated_instance_(instance) { 206 Module::Get()->AddPluginInterface(kPPPContentDecryptorInterface, 207 &ppp_content_decryptor); 208 instance->AddPerInstanceObject(kPPPContentDecryptorInterface, this); 209} 210 211ContentDecryptor_Private::~ContentDecryptor_Private() { 212 Instance::RemovePerInstanceObject(associated_instance_, 213 kPPPContentDecryptorInterface, 214 this); 215} 216 217void ContentDecryptor_Private::NeedKey(const std::string& key_system, 218 const std::string& session_id, 219 pp::VarArrayBuffer init_data) { 220 // session_id can be empty here. 221 if (has_interface<PPB_ContentDecryptor_Private>()) { 222 pp::Var key_system_var(key_system); 223 pp::Var session_id_var(session_id); 224 225 get_interface<PPB_ContentDecryptor_Private>()->NeedKey( 226 associated_instance_.pp_instance(), 227 key_system_var.pp_var(), 228 session_id_var.pp_var(), 229 init_data.pp_var()); 230 } 231} 232 233void ContentDecryptor_Private::KeyAdded(const std::string& key_system, 234 const std::string& session_id) { 235 if (has_interface<PPB_ContentDecryptor_Private>()) { 236 pp::Var key_system_var(key_system); 237 pp::Var session_id_var(session_id); 238 get_interface<PPB_ContentDecryptor_Private>()->KeyAdded( 239 associated_instance_.pp_instance(), 240 key_system_var.pp_var(), 241 session_id_var.pp_var()); 242 } 243} 244 245void ContentDecryptor_Private::KeyMessage(const std::string& key_system, 246 const std::string& session_id, 247 pp::VarArrayBuffer message, 248 const std::string& default_url) { 249 if (has_interface<PPB_ContentDecryptor_Private>()) { 250 pp::Var key_system_var(key_system); 251 pp::Var session_id_var(session_id); 252 pp::Var default_url_var(default_url); 253 get_interface<PPB_ContentDecryptor_Private>()->KeyMessage( 254 associated_instance_.pp_instance(), 255 key_system_var.pp_var(), 256 session_id_var.pp_var(), 257 message.pp_var(), 258 default_url_var.pp_var()); 259 } 260} 261 262void ContentDecryptor_Private::KeyError(const std::string& key_system, 263 const std::string& session_id, 264 int32_t media_error, 265 int32_t system_code) { 266 if (has_interface<PPB_ContentDecryptor_Private>()) { 267 pp::Var key_system_var(key_system); 268 pp::Var session_id_var(session_id); 269 get_interface<PPB_ContentDecryptor_Private>()->KeyError( 270 associated_instance_.pp_instance(), 271 key_system_var.pp_var(), 272 session_id_var.pp_var(), 273 media_error, 274 system_code); 275 } 276} 277 278void ContentDecryptor_Private::DeliverBlock( 279 pp::Buffer_Dev decrypted_block, 280 const PP_DecryptedBlockInfo& decrypted_block_info) { 281 if (has_interface<PPB_ContentDecryptor_Private>()) { 282 get_interface<PPB_ContentDecryptor_Private>()->DeliverBlock( 283 associated_instance_.pp_instance(), 284 decrypted_block.pp_resource(), 285 &decrypted_block_info); 286 } 287} 288 289void ContentDecryptor_Private::DecoderInitializeDone( 290 PP_DecryptorStreamType decoder_type, 291 uint32_t request_id, 292 bool success) { 293 if (has_interface<PPB_ContentDecryptor_Private>()) { 294 get_interface<PPB_ContentDecryptor_Private>()->DecoderInitializeDone( 295 associated_instance_.pp_instance(), 296 decoder_type, 297 request_id, 298 PP_FromBool(success)); 299 } 300} 301 302void ContentDecryptor_Private::DecoderDeinitializeDone( 303 PP_DecryptorStreamType decoder_type, 304 uint32_t request_id) { 305 if (has_interface<PPB_ContentDecryptor_Private>()) { 306 get_interface<PPB_ContentDecryptor_Private>()->DecoderDeinitializeDone( 307 associated_instance_.pp_instance(), 308 decoder_type, 309 request_id); 310 } 311} 312 313void ContentDecryptor_Private::DecoderResetDone( 314 PP_DecryptorStreamType decoder_type, 315 uint32_t request_id) { 316 if (has_interface<PPB_ContentDecryptor_Private>()) { 317 get_interface<PPB_ContentDecryptor_Private>()->DecoderResetDone( 318 associated_instance_.pp_instance(), 319 decoder_type, 320 request_id); 321 } 322} 323 324void ContentDecryptor_Private::DeliverFrame( 325 pp::Buffer_Dev decrypted_frame, 326 const PP_DecryptedFrameInfo& decrypted_frame_info) { 327 if (has_interface<PPB_ContentDecryptor_Private>()) { 328 get_interface<PPB_ContentDecryptor_Private>()->DeliverFrame( 329 associated_instance_.pp_instance(), 330 decrypted_frame.pp_resource(), 331 &decrypted_frame_info); 332 } 333} 334 335void ContentDecryptor_Private::DeliverSamples( 336 pp::Buffer_Dev audio_frames, 337 const PP_DecryptedBlockInfo& decrypted_block_info) { 338 if (has_interface<PPB_ContentDecryptor_Private>()) { 339 get_interface<PPB_ContentDecryptor_Private>()->DeliverSamples( 340 associated_instance_.pp_instance(), 341 audio_frames.pp_resource(), 342 &decrypted_block_info); 343 } 344} 345 346} // namespace pp 347