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 20 namespace pp { 21 22 namespace { 23 24 static const char kPPPContentDecryptorInterface[] = 25 PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 26 27 void 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 42 void 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 59 void 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 85 void 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 101 void 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 123 void 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 139 void 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 155 void 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 171 void 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 186 void 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 202 void 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 218 void 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 230 void 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 241 void 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 258 const 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 274 template <> const char* interface_name<PPB_ContentDecryptor_Private>() { 275 return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 276 } 277 278 } // namespace 279 280 ContentDecryptor_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 287 ContentDecryptor_Private::~ContentDecryptor_Private() { 288 Instance::RemovePerInstanceObject(associated_instance_, 289 kPPPContentDecryptorInterface, 290 this); 291 } 292 293 void 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 300 void 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 312 void 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 329 void 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 345 void 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 360 void 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 372 void 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 384 void 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 392 void 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 401 void 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 418 void 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 429 void 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 442 void 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 453 void 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 464 void 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 475 void 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