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#include "ppapi/cpp/var_array.h" 19 20namespace pp { 21 22namespace { 23 24static const char kPPPContentDecryptorInterface[] = 25 PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 26 27void Initialize(PP_Instance instance, 28 PP_Var key_system_arg) { 29 void* object = 30 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 31 if (!object) 32 return; 33 34 pp::Var key_system_var(pp::PASS_REF, key_system_arg); 35 if (!key_system_var.is_string()) 36 return; 37 38 static_cast<ContentDecryptor_Private*>(object)->Initialize( 39 key_system_var.AsString()); 40} 41 42void SetServerCertificate(PP_Instance instance, 43 uint32_t promise_id, 44 PP_Var server_certificate_arg) { 45 void* object = 46 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 47 if (!object) 48 return; 49 50 pp::Var server_certificate_var(server_certificate_arg); 51 if (!server_certificate_var.is_array_buffer()) 52 return; 53 pp::VarArrayBuffer server_certificate(server_certificate_var); 54 55 static_cast<ContentDecryptor_Private*>(object) 56 ->SetServerCertificate(promise_id, server_certificate); 57} 58 59void CreateSession(PP_Instance instance, 60 uint32_t promise_id, 61 PP_Var init_data_type_arg, 62 PP_Var init_data_arg, 63 PP_SessionType session_type) { 64 void* object = 65 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 66 if (!object) 67 return; 68 69 pp::Var init_data_type_var(pp::PASS_REF, init_data_type_arg); 70 if (!init_data_type_var.is_string()) 71 return; 72 73 pp::Var init_data_var(pp::PASS_REF, init_data_arg); 74 if (!init_data_var.is_array_buffer()) 75 return; 76 pp::VarArrayBuffer init_data_array_buffer(init_data_var); 77 78 static_cast<ContentDecryptor_Private*>(object) 79 ->CreateSession(promise_id, 80 init_data_type_var.AsString(), 81 init_data_array_buffer, 82 session_type); 83} 84 85void LoadSession(PP_Instance instance, 86 uint32_t promise_id, 87 PP_Var web_session_id_arg) { 88 void* object = 89 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 90 if (!object) 91 return; 92 93 pp::Var web_session_id_var(web_session_id_arg); 94 if (!web_session_id_var.is_string()) 95 return; 96 97 static_cast<ContentDecryptor_Private*>(object) 98 ->LoadSession(promise_id, web_session_id_var.AsString()); 99} 100 101void UpdateSession(PP_Instance instance, 102 uint32_t promise_id, 103 PP_Var web_session_id_arg, 104 PP_Var response_arg) { 105 void* object = 106 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 107 if (!object) 108 return; 109 110 pp::Var web_session_id_var(web_session_id_arg); 111 if (!web_session_id_var.is_string()) 112 return; 113 114 pp::Var response_var(response_arg); 115 if (!response_var.is_array_buffer()) 116 return; 117 pp::VarArrayBuffer response(response_var); 118 119 static_cast<ContentDecryptor_Private*>(object) 120 ->UpdateSession(promise_id, web_session_id_var.AsString(), response); 121} 122 123void CloseSession(PP_Instance instance, 124 uint32_t promise_id, 125 PP_Var web_session_id_arg) { 126 void* object = 127 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 128 if (!object) 129 return; 130 131 pp::Var web_session_id_var(web_session_id_arg); 132 if (!web_session_id_var.is_string()) 133 return; 134 135 static_cast<ContentDecryptor_Private*>(object) 136 ->CloseSession(promise_id, web_session_id_var.AsString()); 137} 138 139void RemoveSession(PP_Instance instance, 140 uint32_t promise_id, 141 PP_Var web_session_id_arg) { 142 void* object = 143 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 144 if (!object) 145 return; 146 147 pp::Var web_session_id_var(web_session_id_arg); 148 if (!web_session_id_var.is_string()) 149 return; 150 151 static_cast<ContentDecryptor_Private*>(object) 152 ->RemoveSession(promise_id, web_session_id_var.AsString()); 153} 154 155void GetUsableKeyIds(PP_Instance instance, 156 uint32_t promise_id, 157 PP_Var web_session_id_arg) { 158 void* object = 159 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 160 if (!object) 161 return; 162 163 pp::Var web_session_id_var(web_session_id_arg); 164 if (!web_session_id_var.is_string()) 165 return; 166 167 static_cast<ContentDecryptor_Private*>(object) 168 ->GetUsableKeyIds(promise_id, web_session_id_var.AsString()); 169} 170 171void Decrypt(PP_Instance instance, 172 PP_Resource encrypted_resource, 173 const PP_EncryptedBlockInfo* encrypted_block_info) { 174 pp::Buffer_Dev encrypted_block(encrypted_resource); 175 176 void* object = 177 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 178 if (!object) 179 return; 180 181 static_cast<ContentDecryptor_Private*>(object)->Decrypt( 182 encrypted_block, 183 *encrypted_block_info); 184} 185 186void InitializeAudioDecoder( 187 PP_Instance instance, 188 const PP_AudioDecoderConfig* decoder_config, 189 PP_Resource extra_data_resource) { 190 pp::Buffer_Dev extra_data_buffer(extra_data_resource); 191 192 void* object = 193 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 194 if (!object) 195 return; 196 197 static_cast<ContentDecryptor_Private*>(object)->InitializeAudioDecoder( 198 *decoder_config, 199 extra_data_buffer); 200} 201 202void InitializeVideoDecoder( 203 PP_Instance instance, 204 const PP_VideoDecoderConfig* decoder_config, 205 PP_Resource extra_data_resource) { 206 pp::Buffer_Dev extra_data_buffer(extra_data_resource); 207 208 void* object = 209 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 210 if (!object) 211 return; 212 213 static_cast<ContentDecryptor_Private*>(object)->InitializeVideoDecoder( 214 *decoder_config, 215 extra_data_buffer); 216} 217 218void DeinitializeDecoder(PP_Instance instance, 219 PP_DecryptorStreamType decoder_type, 220 uint32_t request_id) { 221 void* object = 222 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 223 if (!object) 224 return; 225 static_cast<ContentDecryptor_Private*>(object)->DeinitializeDecoder( 226 decoder_type, 227 request_id); 228} 229 230void ResetDecoder(PP_Instance instance, 231 PP_DecryptorStreamType decoder_type, 232 uint32_t request_id) { 233 void* object = 234 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 235 if (!object) 236 return; 237 static_cast<ContentDecryptor_Private*>(object)->ResetDecoder(decoder_type, 238 request_id); 239} 240 241void DecryptAndDecode(PP_Instance instance, 242 PP_DecryptorStreamType decoder_type, 243 PP_Resource encrypted_resource, 244 const PP_EncryptedBlockInfo* encrypted_block_info) { 245 pp::Buffer_Dev encrypted_buffer(encrypted_resource); 246 247 void* object = 248 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 249 if (!object) 250 return; 251 252 static_cast<ContentDecryptor_Private*>(object)->DecryptAndDecode( 253 decoder_type, 254 encrypted_buffer, 255 *encrypted_block_info); 256} 257 258const PPP_ContentDecryptor_Private ppp_content_decryptor = { 259 &Initialize, 260 &SetServerCertificate, 261 &CreateSession, 262 &LoadSession, 263 &UpdateSession, 264 &CloseSession, 265 &RemoveSession, 266 &GetUsableKeyIds, 267 &Decrypt, 268 &InitializeAudioDecoder, 269 &InitializeVideoDecoder, 270 &DeinitializeDecoder, 271 &ResetDecoder, 272 &DecryptAndDecode}; 273 274template <> const char* interface_name<PPB_ContentDecryptor_Private>() { 275 return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 276} 277 278} // namespace 279 280ContentDecryptor_Private::ContentDecryptor_Private(Instance* instance) 281 : associated_instance_(instance) { 282 Module::Get()->AddPluginInterface(kPPPContentDecryptorInterface, 283 &ppp_content_decryptor); 284 instance->AddPerInstanceObject(kPPPContentDecryptorInterface, this); 285} 286 287ContentDecryptor_Private::~ContentDecryptor_Private() { 288 Instance::RemovePerInstanceObject(associated_instance_, 289 kPPPContentDecryptorInterface, 290 this); 291} 292 293void ContentDecryptor_Private::PromiseResolved(uint32_t promise_id) { 294 if (has_interface<PPB_ContentDecryptor_Private>()) { 295 get_interface<PPB_ContentDecryptor_Private>()->PromiseResolved( 296 associated_instance_.pp_instance(), promise_id); 297 } 298} 299 300void ContentDecryptor_Private::PromiseResolvedWithSession( 301 uint32_t promise_id, 302 const std::string& web_session_id) { 303 if (has_interface<PPB_ContentDecryptor_Private>()) { 304 pp::Var web_session_id_var(web_session_id); 305 get_interface<PPB_ContentDecryptor_Private>()->PromiseResolvedWithSession( 306 associated_instance_.pp_instance(), 307 promise_id, 308 web_session_id_var.pp_var()); 309 } 310} 311 312void ContentDecryptor_Private::PromiseResolvedWithKeyIds( 313 uint32_t promise_id, 314 const std::vector<std::vector<uint8_t> >& key_ids) { 315 if (has_interface<PPB_ContentDecryptor_Private>()) { 316 pp::VarArray key_ids_array = pp::VarArray(); 317 key_ids_array.SetLength(key_ids.size()); 318 for (size_t i = 0; i < key_ids.size(); ++i) { 319 const std::vector<uint8_t>& entry = key_ids[i]; 320 pp::VarArrayBuffer array_buffer(entry.size()); 321 memcpy(array_buffer.Map(), &entry[0], entry.size()); 322 key_ids_array.Set(i, array_buffer); 323 } 324 get_interface<PPB_ContentDecryptor_Private>()->PromiseResolvedWithKeyIds( 325 associated_instance_.pp_instance(), promise_id, key_ids_array.pp_var()); 326 } 327} 328 329void ContentDecryptor_Private::PromiseRejected( 330 uint32_t promise_id, 331 PP_CdmExceptionCode exception_code, 332 uint32_t system_code, 333 const std::string& error_description) { 334 if (has_interface<PPB_ContentDecryptor_Private>()) { 335 pp::Var error_description_var(error_description); 336 get_interface<PPB_ContentDecryptor_Private>()->PromiseRejected( 337 associated_instance_.pp_instance(), 338 promise_id, 339 exception_code, 340 system_code, 341 error_description_var.pp_var()); 342 } 343} 344 345void ContentDecryptor_Private::SessionMessage( 346 const std::string& web_session_id, 347 pp::VarArrayBuffer message, 348 const std::string& destination_url) { 349 if (has_interface<PPB_ContentDecryptor_Private>()) { 350 pp::Var web_session_id_var(web_session_id); 351 pp::Var destination_url_var(destination_url); 352 get_interface<PPB_ContentDecryptor_Private>()->SessionMessage( 353 associated_instance_.pp_instance(), 354 web_session_id_var.pp_var(), 355 message.pp_var(), 356 destination_url_var.pp_var()); 357 } 358} 359 360void ContentDecryptor_Private::SessionKeysChange( 361 const std::string& web_session_id, 362 bool has_additional_usable_key) { 363 if (has_interface<PPB_ContentDecryptor_Private>()) { 364 pp::Var web_session_id_var(web_session_id); 365 get_interface<PPB_ContentDecryptor_Private>()->SessionKeysChange( 366 associated_instance_.pp_instance(), 367 web_session_id_var.pp_var(), 368 PP_FromBool(has_additional_usable_key)); 369 } 370} 371 372void ContentDecryptor_Private::SessionExpirationChange( 373 const std::string& web_session_id, 374 PP_Time new_expiry_time) { 375 if (has_interface<PPB_ContentDecryptor_Private>()) { 376 pp::Var web_session_id_var(web_session_id); 377 get_interface<PPB_ContentDecryptor_Private>()->SessionExpirationChange( 378 associated_instance_.pp_instance(), 379 web_session_id_var.pp_var(), 380 new_expiry_time); 381 } 382} 383 384void ContentDecryptor_Private::SessionReady(const std::string& web_session_id) { 385 if (has_interface<PPB_ContentDecryptor_Private>()) { 386 pp::Var web_session_id_var(web_session_id); 387 get_interface<PPB_ContentDecryptor_Private>()->SessionReady( 388 associated_instance_.pp_instance(), web_session_id_var.pp_var()); 389 } 390} 391 392void ContentDecryptor_Private::SessionClosed( 393 const std::string& web_session_id) { 394 if (has_interface<PPB_ContentDecryptor_Private>()) { 395 pp::Var web_session_id_var(web_session_id); 396 get_interface<PPB_ContentDecryptor_Private>()->SessionClosed( 397 associated_instance_.pp_instance(), web_session_id_var.pp_var()); 398 } 399} 400 401void ContentDecryptor_Private::SessionError( 402 const std::string& web_session_id, 403 PP_CdmExceptionCode exception_code, 404 uint32_t system_code, 405 const std::string& error_description) { 406 if (has_interface<PPB_ContentDecryptor_Private>()) { 407 pp::Var web_session_id_var(web_session_id); 408 pp::Var error_description_var(error_description); 409 get_interface<PPB_ContentDecryptor_Private>()->SessionError( 410 associated_instance_.pp_instance(), 411 web_session_id_var.pp_var(), 412 exception_code, 413 system_code, 414 error_description_var.pp_var()); 415 } 416} 417 418void ContentDecryptor_Private::DeliverBlock( 419 pp::Buffer_Dev decrypted_block, 420 const PP_DecryptedBlockInfo& decrypted_block_info) { 421 if (has_interface<PPB_ContentDecryptor_Private>()) { 422 get_interface<PPB_ContentDecryptor_Private>()->DeliverBlock( 423 associated_instance_.pp_instance(), 424 decrypted_block.pp_resource(), 425 &decrypted_block_info); 426 } 427} 428 429void ContentDecryptor_Private::DecoderInitializeDone( 430 PP_DecryptorStreamType decoder_type, 431 uint32_t request_id, 432 bool success) { 433 if (has_interface<PPB_ContentDecryptor_Private>()) { 434 get_interface<PPB_ContentDecryptor_Private>()->DecoderInitializeDone( 435 associated_instance_.pp_instance(), 436 decoder_type, 437 request_id, 438 PP_FromBool(success)); 439 } 440} 441 442void ContentDecryptor_Private::DecoderDeinitializeDone( 443 PP_DecryptorStreamType decoder_type, 444 uint32_t request_id) { 445 if (has_interface<PPB_ContentDecryptor_Private>()) { 446 get_interface<PPB_ContentDecryptor_Private>()->DecoderDeinitializeDone( 447 associated_instance_.pp_instance(), 448 decoder_type, 449 request_id); 450 } 451} 452 453void ContentDecryptor_Private::DecoderResetDone( 454 PP_DecryptorStreamType decoder_type, 455 uint32_t request_id) { 456 if (has_interface<PPB_ContentDecryptor_Private>()) { 457 get_interface<PPB_ContentDecryptor_Private>()->DecoderResetDone( 458 associated_instance_.pp_instance(), 459 decoder_type, 460 request_id); 461 } 462} 463 464void ContentDecryptor_Private::DeliverFrame( 465 pp::Buffer_Dev decrypted_frame, 466 const PP_DecryptedFrameInfo& decrypted_frame_info) { 467 if (has_interface<PPB_ContentDecryptor_Private>()) { 468 get_interface<PPB_ContentDecryptor_Private>()->DeliverFrame( 469 associated_instance_.pp_instance(), 470 decrypted_frame.pp_resource(), 471 &decrypted_frame_info); 472 } 473} 474 475void ContentDecryptor_Private::DeliverSamples( 476 pp::Buffer_Dev audio_frames, 477 const PP_DecryptedSampleInfo& decrypted_sample_info) { 478 if (has_interface<PPB_ContentDecryptor_Private>()) { 479 get_interface<PPB_ContentDecryptor_Private>()->DeliverSamples( 480 associated_instance_.pp_instance(), 481 audio_frames.pp_resource(), 482 &decrypted_sample_info); 483 } 484} 485 486} // namespace pp 487