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 session_id, 43 PP_Var type_arg, 44 PP_Var init_data_arg) { 45 void* object = 46 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 47 if (!object) 48 return; 49 50 pp::Var type_var(pp::PASS_REF, type_arg); 51 if (!type_var.is_string()) 52 return; 53 54 pp::Var init_data_var(pp::PASS_REF, init_data_arg); 55 if (!init_data_var.is_array_buffer()) 56 return; 57 pp::VarArrayBuffer init_data_array_buffer(init_data_var); 58 59 static_cast<ContentDecryptor_Private*>(object) 60 ->CreateSession(session_id, type_var.AsString(), init_data_array_buffer); 61 } 62 63 void UpdateSession(PP_Instance instance, 64 uint32_t session_id, 65 PP_Var response_arg) { 66 void* object = 67 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 68 if (!object) 69 return; 70 71 pp::Var response_var(pp::PASS_REF, response_arg); 72 if (!response_var.is_array_buffer()) 73 return; 74 pp::VarArrayBuffer response(response_var); 75 76 static_cast<ContentDecryptor_Private*>(object) 77 ->UpdateSession(session_id, response); 78 } 79 80 void ReleaseSession(PP_Instance instance, uint32_t session_id) { 81 void* object = 82 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 83 if (!object) 84 return; 85 86 static_cast<ContentDecryptor_Private*>(object)->ReleaseSession(session_id); 87 } 88 89 90 void Decrypt(PP_Instance instance, 91 PP_Resource encrypted_resource, 92 const PP_EncryptedBlockInfo* encrypted_block_info) { 93 pp::Buffer_Dev encrypted_block(encrypted_resource); 94 95 void* object = 96 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 97 if (!object) 98 return; 99 100 static_cast<ContentDecryptor_Private*>(object)->Decrypt( 101 encrypted_block, 102 *encrypted_block_info); 103 } 104 105 void InitializeAudioDecoder( 106 PP_Instance instance, 107 const PP_AudioDecoderConfig* decoder_config, 108 PP_Resource extra_data_resource) { 109 pp::Buffer_Dev extra_data_buffer(extra_data_resource); 110 111 void* object = 112 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 113 if (!object) 114 return; 115 116 static_cast<ContentDecryptor_Private*>(object)->InitializeAudioDecoder( 117 *decoder_config, 118 extra_data_buffer); 119 } 120 121 void InitializeVideoDecoder( 122 PP_Instance instance, 123 const PP_VideoDecoderConfig* decoder_config, 124 PP_Resource extra_data_resource) { 125 pp::Buffer_Dev extra_data_buffer(extra_data_resource); 126 127 void* object = 128 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 129 if (!object) 130 return; 131 132 static_cast<ContentDecryptor_Private*>(object)->InitializeVideoDecoder( 133 *decoder_config, 134 extra_data_buffer); 135 } 136 137 void DeinitializeDecoder(PP_Instance instance, 138 PP_DecryptorStreamType decoder_type, 139 uint32_t request_id) { 140 void* object = 141 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 142 if (!object) 143 return; 144 static_cast<ContentDecryptor_Private*>(object)->DeinitializeDecoder( 145 decoder_type, 146 request_id); 147 } 148 149 void ResetDecoder(PP_Instance instance, 150 PP_DecryptorStreamType decoder_type, 151 uint32_t request_id) { 152 void* object = 153 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 154 if (!object) 155 return; 156 static_cast<ContentDecryptor_Private*>(object)->ResetDecoder(decoder_type, 157 request_id); 158 } 159 160 void DecryptAndDecode(PP_Instance instance, 161 PP_DecryptorStreamType decoder_type, 162 PP_Resource encrypted_resource, 163 const PP_EncryptedBlockInfo* encrypted_block_info) { 164 pp::Buffer_Dev encrypted_buffer(encrypted_resource); 165 166 void* object = 167 Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); 168 if (!object) 169 return; 170 171 static_cast<ContentDecryptor_Private*>(object)->DecryptAndDecode( 172 decoder_type, 173 encrypted_buffer, 174 *encrypted_block_info); 175 } 176 177 const PPP_ContentDecryptor_Private ppp_content_decryptor = { 178 &Initialize, 179 &CreateSession, 180 &UpdateSession, 181 &ReleaseSession, 182 &Decrypt, 183 &InitializeAudioDecoder, 184 &InitializeVideoDecoder, 185 &DeinitializeDecoder, 186 &ResetDecoder, 187 &DecryptAndDecode 188 }; 189 190 template <> const char* interface_name<PPB_ContentDecryptor_Private>() { 191 return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE; 192 } 193 194 } // namespace 195 196 ContentDecryptor_Private::ContentDecryptor_Private(Instance* instance) 197 : associated_instance_(instance) { 198 Module::Get()->AddPluginInterface(kPPPContentDecryptorInterface, 199 &ppp_content_decryptor); 200 instance->AddPerInstanceObject(kPPPContentDecryptorInterface, this); 201 } 202 203 ContentDecryptor_Private::~ContentDecryptor_Private() { 204 Instance::RemovePerInstanceObject(associated_instance_, 205 kPPPContentDecryptorInterface, 206 this); 207 } 208 209 void ContentDecryptor_Private::SessionCreated( 210 uint32_t session_id, 211 const std::string& web_session_id) { 212 if (has_interface<PPB_ContentDecryptor_Private>()) { 213 pp::Var web_session_id_var(web_session_id); 214 get_interface<PPB_ContentDecryptor_Private>()->SessionCreated( 215 associated_instance_.pp_instance(), 216 session_id, 217 web_session_id_var.pp_var()); 218 } 219 } 220 221 void ContentDecryptor_Private::SessionMessage(uint32_t session_id, 222 pp::VarArrayBuffer message, 223 const std::string& default_url) { 224 if (has_interface<PPB_ContentDecryptor_Private>()) { 225 pp::Var default_url_var(default_url); 226 get_interface<PPB_ContentDecryptor_Private>()->SessionMessage( 227 associated_instance_.pp_instance(), 228 session_id, 229 message.pp_var(), 230 default_url_var.pp_var()); 231 } 232 } 233 234 void ContentDecryptor_Private::SessionReady(uint32_t session_id) { 235 if (has_interface<PPB_ContentDecryptor_Private>()) { 236 get_interface<PPB_ContentDecryptor_Private>()->SessionReady( 237 associated_instance_.pp_instance(), session_id); 238 } 239 } 240 241 void ContentDecryptor_Private::SessionClosed(uint32_t session_id) { 242 if (has_interface<PPB_ContentDecryptor_Private>()) { 243 get_interface<PPB_ContentDecryptor_Private>()->SessionClosed( 244 associated_instance_.pp_instance(), session_id); 245 } 246 } 247 248 void ContentDecryptor_Private::SessionError(uint32_t session_id, 249 int32_t media_error, 250 int32_t system_code) { 251 if (has_interface<PPB_ContentDecryptor_Private>()) { 252 get_interface<PPB_ContentDecryptor_Private>()->SessionError( 253 associated_instance_.pp_instance(), 254 session_id, 255 media_error, 256 system_code); 257 } 258 } 259 260 void ContentDecryptor_Private::DeliverBlock( 261 pp::Buffer_Dev decrypted_block, 262 const PP_DecryptedBlockInfo& decrypted_block_info) { 263 if (has_interface<PPB_ContentDecryptor_Private>()) { 264 get_interface<PPB_ContentDecryptor_Private>()->DeliverBlock( 265 associated_instance_.pp_instance(), 266 decrypted_block.pp_resource(), 267 &decrypted_block_info); 268 } 269 } 270 271 void ContentDecryptor_Private::DecoderInitializeDone( 272 PP_DecryptorStreamType decoder_type, 273 uint32_t request_id, 274 bool success) { 275 if (has_interface<PPB_ContentDecryptor_Private>()) { 276 get_interface<PPB_ContentDecryptor_Private>()->DecoderInitializeDone( 277 associated_instance_.pp_instance(), 278 decoder_type, 279 request_id, 280 PP_FromBool(success)); 281 } 282 } 283 284 void ContentDecryptor_Private::DecoderDeinitializeDone( 285 PP_DecryptorStreamType decoder_type, 286 uint32_t request_id) { 287 if (has_interface<PPB_ContentDecryptor_Private>()) { 288 get_interface<PPB_ContentDecryptor_Private>()->DecoderDeinitializeDone( 289 associated_instance_.pp_instance(), 290 decoder_type, 291 request_id); 292 } 293 } 294 295 void ContentDecryptor_Private::DecoderResetDone( 296 PP_DecryptorStreamType decoder_type, 297 uint32_t request_id) { 298 if (has_interface<PPB_ContentDecryptor_Private>()) { 299 get_interface<PPB_ContentDecryptor_Private>()->DecoderResetDone( 300 associated_instance_.pp_instance(), 301 decoder_type, 302 request_id); 303 } 304 } 305 306 void ContentDecryptor_Private::DeliverFrame( 307 pp::Buffer_Dev decrypted_frame, 308 const PP_DecryptedFrameInfo& decrypted_frame_info) { 309 if (has_interface<PPB_ContentDecryptor_Private>()) { 310 get_interface<PPB_ContentDecryptor_Private>()->DeliverFrame( 311 associated_instance_.pp_instance(), 312 decrypted_frame.pp_resource(), 313 &decrypted_frame_info); 314 } 315 } 316 317 void ContentDecryptor_Private::DeliverSamples( 318 pp::Buffer_Dev audio_frames, 319 const PP_DecryptedSampleInfo& decrypted_sample_info) { 320 if (has_interface<PPB_ContentDecryptor_Private>()) { 321 get_interface<PPB_ContentDecryptor_Private>()->DeliverSamples( 322 associated_instance_.pp_instance(), 323 audio_frames.pp_resource(), 324 &decrypted_sample_info); 325 } 326 } 327 328 } // namespace pp 329