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 19 namespace pp { 20 21 namespace { 22 23 static const char kPPPContentDecryptorInterface[] = 24 PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 25 26 void Initialize(PP_Instance instance, 27 PP_Var key_system_arg) { 28 void* object = 29 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 30 if (!object) 31 return; 32 33 pp::Var key_system_var(pp::PASS_REF, key_system_arg); 34 if (!key_system_var.is_string()) 35 return; 36 37 static_cast<ContentDecryptor_Private*>(object)->Initialize( 38 key_system_var.AsString()); 39 } 40 41 void CreateSession(PP_Instance instance, 42 uint32_t promise_id, 43 PP_Var init_data_type_arg, 44 PP_Var init_data_arg, 45 PP_SessionType session_type) { 46 void* object = 47 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 48 if (!object) 49 return; 50 51 pp::Var init_data_type_var(pp::PASS_REF, init_data_type_arg); 52 if (!init_data_type_var.is_string()) 53 return; 54 55 pp::Var init_data_var(pp::PASS_REF, init_data_arg); 56 if (!init_data_var.is_array_buffer()) 57 return; 58 pp::VarArrayBuffer init_data_array_buffer(init_data_var); 59 60 static_cast<ContentDecryptor_Private*>(object) 61 ->CreateSession(promise_id, 62 init_data_type_var.AsString(), 63 init_data_array_buffer, 64 session_type); 65 } 66 67 void LoadSession(PP_Instance instance, 68 uint32_t promise_id, 69 PP_Var web_session_id_arg) { 70 void* object = 71 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 72 if (!object) 73 return; 74 75 pp::Var web_session_id_var(web_session_id_arg); 76 if (!web_session_id_var.is_string()) 77 return; 78 79 static_cast<ContentDecryptor_Private*>(object) 80 ->LoadSession(promise_id, web_session_id_var.AsString()); 81 } 82 83 void UpdateSession(PP_Instance instance, 84 uint32_t promise_id, 85 PP_Var web_session_id_arg, 86 PP_Var response_arg) { 87 void* object = 88 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 89 if (!object) 90 return; 91 92 pp::Var web_session_id_var(web_session_id_arg); 93 if (!web_session_id_var.is_string()) 94 return; 95 96 pp::Var response_var(response_arg); 97 if (!response_var.is_array_buffer()) 98 return; 99 pp::VarArrayBuffer response(response_var); 100 101 static_cast<ContentDecryptor_Private*>(object) 102 ->UpdateSession(promise_id, web_session_id_var.AsString(), response); 103 } 104 105 void ReleaseSession(PP_Instance instance, 106 uint32_t promise_id, 107 PP_Var web_session_id_arg) { 108 void* object = 109 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 110 if (!object) 111 return; 112 113 pp::Var web_session_id_var(web_session_id_arg); 114 if (!web_session_id_var.is_string()) 115 return; 116 117 static_cast<ContentDecryptor_Private*>(object) 118 ->ReleaseSession(promise_id, web_session_id_var.AsString()); 119 } 120 121 void Decrypt(PP_Instance instance, 122 PP_Resource encrypted_resource, 123 const PP_EncryptedBlockInfo* encrypted_block_info) { 124 pp::Buffer_Dev encrypted_block(encrypted_resource); 125 126 void* object = 127 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 128 if (!object) 129 return; 130 131 static_cast<ContentDecryptor_Private*>(object)->Decrypt( 132 encrypted_block, 133 *encrypted_block_info); 134 } 135 136 void InitializeAudioDecoder( 137 PP_Instance instance, 138 const PP_AudioDecoderConfig* decoder_config, 139 PP_Resource extra_data_resource) { 140 pp::Buffer_Dev extra_data_buffer(extra_data_resource); 141 142 void* object = 143 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 144 if (!object) 145 return; 146 147 static_cast<ContentDecryptor_Private*>(object)->InitializeAudioDecoder( 148 *decoder_config, 149 extra_data_buffer); 150 } 151 152 void InitializeVideoDecoder( 153 PP_Instance instance, 154 const PP_VideoDecoderConfig* decoder_config, 155 PP_Resource extra_data_resource) { 156 pp::Buffer_Dev extra_data_buffer(extra_data_resource); 157 158 void* object = 159 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 160 if (!object) 161 return; 162 163 static_cast<ContentDecryptor_Private*>(object)->InitializeVideoDecoder( 164 *decoder_config, 165 extra_data_buffer); 166 } 167 168 void DeinitializeDecoder(PP_Instance instance, 169 PP_DecryptorStreamType decoder_type, 170 uint32_t request_id) { 171 void* object = 172 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 173 if (!object) 174 return; 175 static_cast<ContentDecryptor_Private*>(object)->DeinitializeDecoder( 176 decoder_type, 177 request_id); 178 } 179 180 void ResetDecoder(PP_Instance instance, 181 PP_DecryptorStreamType decoder_type, 182 uint32_t request_id) { 183 void* object = 184 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 185 if (!object) 186 return; 187 static_cast<ContentDecryptor_Private*>(object)->ResetDecoder(decoder_type, 188 request_id); 189 } 190 191 void DecryptAndDecode(PP_Instance instance, 192 PP_DecryptorStreamType decoder_type, 193 PP_Resource encrypted_resource, 194 const PP_EncryptedBlockInfo* encrypted_block_info) { 195 pp::Buffer_Dev encrypted_buffer(encrypted_resource); 196 197 void* object = 198 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 199 if (!object) 200 return; 201 202 static_cast<ContentDecryptor_Private*>(object)->DecryptAndDecode( 203 decoder_type, 204 encrypted_buffer, 205 *encrypted_block_info); 206 } 207 208 const PPP_ContentDecryptor_Private ppp_content_decryptor = { 209 &Initialize, 210 &CreateSession, 211 &LoadSession, 212 &UpdateSession, 213 &ReleaseSession, 214 &Decrypt, 215 &InitializeAudioDecoder, 216 &InitializeVideoDecoder, 217 &DeinitializeDecoder, 218 &ResetDecoder, 219 &DecryptAndDecode 220 }; 221 222 template <> const char* interface_name<PPB_ContentDecryptor_Private>() { 223 return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 224 } 225 226 } // namespace 227 228 ContentDecryptor_Private::ContentDecryptor_Private(Instance* instance) 229 : associated_instance_(instance) { 230 Module::Get()->AddPluginInterface(kPPPContentDecryptorInterface, 231 &ppp_content_decryptor); 232 instance->AddPerInstanceObject(kPPPContentDecryptorInterface, this); 233 } 234 235 ContentDecryptor_Private::~ContentDecryptor_Private() { 236 Instance::RemovePerInstanceObject(associated_instance_, 237 kPPPContentDecryptorInterface, 238 this); 239 } 240 241 void ContentDecryptor_Private::PromiseResolved(uint32_t promise_id) { 242 if (has_interface<PPB_ContentDecryptor_Private>()) { 243 get_interface<PPB_ContentDecryptor_Private>()->PromiseResolved( 244 associated_instance_.pp_instance(), promise_id); 245 } 246 } 247 248 void ContentDecryptor_Private::PromiseResolvedWithSession( 249 uint32_t promise_id, 250 const std::string& web_session_id) { 251 if (has_interface<PPB_ContentDecryptor_Private>()) { 252 pp::Var web_session_id_var(web_session_id); 253 get_interface<PPB_ContentDecryptor_Private>()->PromiseResolvedWithSession( 254 associated_instance_.pp_instance(), 255 promise_id, 256 web_session_id_var.pp_var()); 257 } 258 } 259 260 void ContentDecryptor_Private::PromiseRejected( 261 uint32_t promise_id, 262 PP_CdmExceptionCode exception_code, 263 uint32_t system_code, 264 const std::string& error_description) { 265 if (has_interface<PPB_ContentDecryptor_Private>()) { 266 pp::Var error_description_var(error_description); 267 get_interface<PPB_ContentDecryptor_Private>()->PromiseRejected( 268 associated_instance_.pp_instance(), 269 promise_id, 270 exception_code, 271 system_code, 272 error_description_var.pp_var()); 273 } 274 } 275 276 void ContentDecryptor_Private::SessionMessage( 277 const std::string& web_session_id, 278 pp::VarArrayBuffer message, 279 const std::string& destination_url) { 280 if (has_interface<PPB_ContentDecryptor_Private>()) { 281 pp::Var web_session_id_var(web_session_id); 282 pp::Var destination_url_var(destination_url); 283 get_interface<PPB_ContentDecryptor_Private>()->SessionMessage( 284 associated_instance_.pp_instance(), 285 web_session_id_var.pp_var(), 286 message.pp_var(), 287 destination_url_var.pp_var()); 288 } 289 } 290 291 void ContentDecryptor_Private::SessionReady(const std::string& web_session_id) { 292 if (has_interface<PPB_ContentDecryptor_Private>()) { 293 pp::Var web_session_id_var(web_session_id); 294 get_interface<PPB_ContentDecryptor_Private>()->SessionReady( 295 associated_instance_.pp_instance(), web_session_id_var.pp_var()); 296 } 297 } 298 299 void ContentDecryptor_Private::SessionClosed( 300 const std::string& web_session_id) { 301 if (has_interface<PPB_ContentDecryptor_Private>()) { 302 pp::Var web_session_id_var(web_session_id); 303 get_interface<PPB_ContentDecryptor_Private>()->SessionClosed( 304 associated_instance_.pp_instance(), web_session_id_var.pp_var()); 305 } 306 } 307 308 void ContentDecryptor_Private::SessionError( 309 const std::string& web_session_id, 310 PP_CdmExceptionCode exception_code, 311 uint32_t system_code, 312 const std::string& error_description) { 313 if (has_interface<PPB_ContentDecryptor_Private>()) { 314 pp::Var web_session_id_var(web_session_id); 315 pp::Var error_description_var(error_description); 316 get_interface<PPB_ContentDecryptor_Private>()->SessionError( 317 associated_instance_.pp_instance(), 318 web_session_id_var.pp_var(), 319 exception_code, 320 system_code, 321 error_description_var.pp_var()); 322 } 323 } 324 325 void ContentDecryptor_Private::DeliverBlock( 326 pp::Buffer_Dev decrypted_block, 327 const PP_DecryptedBlockInfo& decrypted_block_info) { 328 if (has_interface<PPB_ContentDecryptor_Private>()) { 329 get_interface<PPB_ContentDecryptor_Private>()->DeliverBlock( 330 associated_instance_.pp_instance(), 331 decrypted_block.pp_resource(), 332 &decrypted_block_info); 333 } 334 } 335 336 void ContentDecryptor_Private::DecoderInitializeDone( 337 PP_DecryptorStreamType decoder_type, 338 uint32_t request_id, 339 bool success) { 340 if (has_interface<PPB_ContentDecryptor_Private>()) { 341 get_interface<PPB_ContentDecryptor_Private>()->DecoderInitializeDone( 342 associated_instance_.pp_instance(), 343 decoder_type, 344 request_id, 345 PP_FromBool(success)); 346 } 347 } 348 349 void ContentDecryptor_Private::DecoderDeinitializeDone( 350 PP_DecryptorStreamType decoder_type, 351 uint32_t request_id) { 352 if (has_interface<PPB_ContentDecryptor_Private>()) { 353 get_interface<PPB_ContentDecryptor_Private>()->DecoderDeinitializeDone( 354 associated_instance_.pp_instance(), 355 decoder_type, 356 request_id); 357 } 358 } 359 360 void ContentDecryptor_Private::DecoderResetDone( 361 PP_DecryptorStreamType decoder_type, 362 uint32_t request_id) { 363 if (has_interface<PPB_ContentDecryptor_Private>()) { 364 get_interface<PPB_ContentDecryptor_Private>()->DecoderResetDone( 365 associated_instance_.pp_instance(), 366 decoder_type, 367 request_id); 368 } 369 } 370 371 void ContentDecryptor_Private::DeliverFrame( 372 pp::Buffer_Dev decrypted_frame, 373 const PP_DecryptedFrameInfo& decrypted_frame_info) { 374 if (has_interface<PPB_ContentDecryptor_Private>()) { 375 get_interface<PPB_ContentDecryptor_Private>()->DeliverFrame( 376 associated_instance_.pp_instance(), 377 decrypted_frame.pp_resource(), 378 &decrypted_frame_info); 379 } 380 } 381 382 void ContentDecryptor_Private::DeliverSamples( 383 pp::Buffer_Dev audio_frames, 384 const PP_DecryptedSampleInfo& decrypted_sample_info) { 385 if (has_interface<PPB_ContentDecryptor_Private>()) { 386 get_interface<PPB_ContentDecryptor_Private>()->DeliverSamples( 387 associated_instance_.pp_instance(), 388 audio_frames.pp_resource(), 389 &decrypted_sample_info); 390 } 391 } 392 393 } // namespace pp 394