Home | History | Annotate | Download | only in private
      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