Home | History | Annotate | Download | only in proxy
      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/proxy/ppp_content_decryptor_private_proxy.h"
      6 
      7 #include "base/files/file.h"
      8 #include "media/base/limits.h"
      9 #include "ppapi/c/pp_bool.h"
     10 #include "ppapi/c/ppb_core.h"
     11 #include "ppapi/proxy/content_decryptor_private_serializer.h"
     12 #include "ppapi/proxy/host_dispatcher.h"
     13 #include "ppapi/proxy/plugin_globals.h"
     14 #include "ppapi/proxy/plugin_resource_tracker.h"
     15 #include "ppapi/proxy/ppapi_messages.h"
     16 #include "ppapi/proxy/ppb_buffer_proxy.h"
     17 #include "ppapi/proxy/serialized_var.h"
     18 #include "ppapi/shared_impl/scoped_pp_resource.h"
     19 #include "ppapi/shared_impl/scoped_pp_var.h"
     20 #include "ppapi/shared_impl/var_tracker.h"
     21 #include "ppapi/thunk/enter.h"
     22 #include "ppapi/thunk/ppb_buffer_api.h"
     23 #include "ppapi/thunk/ppb_instance_api.h"
     24 #include "ppapi/thunk/thunk.h"
     25 
     26 using ppapi::thunk::EnterResourceNoLock;
     27 using ppapi::thunk::PPB_Buffer_API;
     28 using ppapi::thunk::PPB_Instance_API;
     29 
     30 namespace ppapi {
     31 namespace proxy {
     32 
     33 namespace {
     34 
     35 PP_Bool DescribeHostBufferResource(PP_Resource resource, uint32_t* size) {
     36   EnterResourceNoLock<PPB_Buffer_API> enter(resource, true);
     37   if (enter.failed())
     38     return PP_FALSE;
     39   return enter.object()->Describe(size);
     40 }
     41 
     42 // TODO(dmichael): Refactor so this handle sharing code is in one place.
     43 PP_Bool ShareHostBufferResourceToPlugin(
     44     HostDispatcher* dispatcher,
     45     PP_Resource resource,
     46     base::SharedMemoryHandle* shared_mem_handle) {
     47   if (!dispatcher || resource == 0 || !shared_mem_handle)
     48     return PP_FALSE;
     49   EnterResourceNoLock<PPB_Buffer_API> enter(resource, true);
     50   if (enter.failed())
     51     return PP_FALSE;
     52   int handle;
     53   int32_t result = enter.object()->GetSharedMemory(&handle);
     54   if (result != PP_OK)
     55     return PP_FALSE;
     56   base::PlatformFile platform_file =
     57   #if defined(OS_WIN)
     58       reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle));
     59   #elif defined(OS_POSIX)
     60       handle;
     61   #else
     62   #error Not implemented.
     63   #endif
     64 
     65   *shared_mem_handle = dispatcher->ShareHandleWithRemote(platform_file, false);
     66   return PP_TRUE;
     67 }
     68 
     69 // SerializedVarReceiveInput will decrement the reference count, but we want
     70 // to give the recipient a reference. This utility function takes care of that
     71 // work for the message handlers defined below.
     72 PP_Var ExtractReceivedVarAndAddRef(Dispatcher* dispatcher,
     73                                    SerializedVarReceiveInput* serialized_var) {
     74   PP_Var var = serialized_var->Get(dispatcher);
     75   PpapiGlobals::Get()->GetVarTracker()->AddRefVar(var);
     76   return var;
     77 }
     78 
     79 bool InitializePppDecryptorBuffer(PP_Instance instance,
     80                                   HostDispatcher* dispatcher,
     81                                   PP_Resource resource,
     82                                   PPPDecryptor_Buffer* buffer) {
     83   if (!buffer) {
     84     NOTREACHED();
     85     return false;
     86   }
     87 
     88   if (resource == 0) {
     89     buffer->resource = HostResource();
     90     buffer->handle = base::SharedMemoryHandle();
     91     buffer->size = 0;
     92     return true;
     93   }
     94 
     95   HostResource host_resource;
     96   host_resource.SetHostResource(instance, resource);
     97 
     98   uint32_t size = 0;
     99   if (DescribeHostBufferResource(resource, &size) == PP_FALSE)
    100     return false;
    101 
    102   base::SharedMemoryHandle handle;
    103   if (ShareHostBufferResourceToPlugin(dispatcher,
    104                                       resource,
    105                                       &handle) == PP_FALSE)
    106     return false;
    107 
    108   buffer->resource = host_resource;
    109   buffer->handle = handle;
    110   buffer->size = size;
    111   return true;
    112 }
    113 
    114 void Initialize(PP_Instance instance,
    115                 PP_Var key_system) {
    116   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    117   if (!dispatcher) {
    118     NOTREACHED();
    119     return;
    120   }
    121 
    122   dispatcher->Send(
    123       new PpapiMsg_PPPContentDecryptor_Initialize(
    124           API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    125           instance,
    126           SerializedVarSendInput(dispatcher, key_system)));
    127 }
    128 
    129 void SetServerCertificate(PP_Instance instance,
    130                           uint32_t promise_id,
    131                           PP_Var server_certificate) {
    132   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    133   if (!dispatcher) {
    134     NOTREACHED();
    135     return;
    136   }
    137 
    138   ArrayBufferVar* server_certificate_buffer =
    139       ArrayBufferVar::FromPPVar(server_certificate);
    140   if (!server_certificate_buffer ||
    141       server_certificate_buffer->ByteLength() <
    142           media::limits::kMinCertificateLength ||
    143       server_certificate_buffer->ByteLength() >
    144           media::limits::kMaxCertificateLength) {
    145     NOTREACHED();
    146     return;
    147   }
    148 
    149   const uint8_t* server_certificate_ptr =
    150       static_cast<const uint8_t*>(server_certificate_buffer->Map());
    151   const uint32_t server_certificate_size =
    152       server_certificate_buffer->ByteLength();
    153   std::vector<uint8_t> server_certificate_vector(
    154       server_certificate_ptr, server_certificate_ptr + server_certificate_size);
    155 
    156   dispatcher->Send(new PpapiMsg_PPPContentDecryptor_SetServerCertificate(
    157       API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    158       instance,
    159       promise_id,
    160       server_certificate_vector));
    161 }
    162 
    163 void CreateSession(PP_Instance instance,
    164                    uint32_t promise_id,
    165                    PP_Var init_data_type,
    166                    PP_Var init_data,
    167                    PP_SessionType session_type) {
    168   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    169   if (!dispatcher) {
    170     NOTREACHED();
    171     return;
    172   }
    173 
    174   dispatcher->Send(new PpapiMsg_PPPContentDecryptor_CreateSession(
    175       API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    176       instance,
    177       promise_id,
    178       SerializedVarSendInput(dispatcher, init_data_type),
    179       SerializedVarSendInput(dispatcher, init_data),
    180       session_type));
    181 }
    182 
    183 void LoadSession(PP_Instance instance,
    184                  uint32_t promise_id,
    185                  PP_Var web_session_id) {
    186   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    187   if (!dispatcher) {
    188     NOTREACHED();
    189     return;
    190   }
    191 
    192   dispatcher->Send(new PpapiMsg_PPPContentDecryptor_LoadSession(
    193       API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    194       instance,
    195       promise_id,
    196       SerializedVarSendInput(dispatcher, web_session_id)));
    197 }
    198 
    199 void UpdateSession(PP_Instance instance,
    200                    uint32_t promise_id,
    201                    PP_Var web_session_id,
    202                    PP_Var response) {
    203   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    204   if (!dispatcher) {
    205     NOTREACHED();
    206     return;
    207   }
    208 
    209   dispatcher->Send(new PpapiMsg_PPPContentDecryptor_UpdateSession(
    210       API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    211       instance,
    212       promise_id,
    213       SerializedVarSendInput(dispatcher, web_session_id),
    214       SerializedVarSendInput(dispatcher, response)));
    215 }
    216 
    217 void CloseSession(PP_Instance instance,
    218                   uint32_t promise_id,
    219                   PP_Var web_session_id) {
    220   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    221   if (!dispatcher) {
    222     NOTREACHED();
    223     return;
    224   }
    225 
    226   StringVar* session_id = StringVar::FromPPVar(web_session_id);
    227   if (!session_id ||
    228       session_id->value().length() > media::limits::kMaxWebSessionIdLength) {
    229     NOTREACHED();
    230     return;
    231   }
    232 
    233   dispatcher->Send(new PpapiMsg_PPPContentDecryptor_CloseSession(
    234       API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    235       instance,
    236       promise_id,
    237       session_id->value()));
    238 }
    239 
    240 void RemoveSession(PP_Instance instance,
    241                    uint32_t promise_id,
    242                    PP_Var web_session_id) {
    243   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    244   if (!dispatcher) {
    245     NOTREACHED();
    246     return;
    247   }
    248 
    249   StringVar* session_id = StringVar::FromPPVar(web_session_id);
    250   if (!session_id ||
    251       session_id->value().length() > media::limits::kMaxWebSessionIdLength) {
    252     NOTREACHED();
    253     return;
    254   }
    255 
    256   dispatcher->Send(new PpapiMsg_PPPContentDecryptor_RemoveSession(
    257       API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    258       instance,
    259       promise_id,
    260       session_id->value()));
    261 }
    262 
    263 void GetUsableKeyIds(PP_Instance instance,
    264                      uint32_t promise_id,
    265                      PP_Var web_session_id) {
    266   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    267   if (!dispatcher) {
    268     NOTREACHED();
    269     return;
    270   }
    271 
    272   StringVar* session_id = StringVar::FromPPVar(web_session_id);
    273   if (!session_id ||
    274       session_id->value().length() > media::limits::kMaxWebSessionIdLength) {
    275     NOTREACHED();
    276     return;
    277   }
    278 
    279   dispatcher->Send(new PpapiMsg_PPPContentDecryptor_GetUsableKeyIds(
    280       API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    281       instance,
    282       promise_id,
    283       session_id->value()));
    284 }
    285 
    286 void Decrypt(PP_Instance instance,
    287              PP_Resource encrypted_block,
    288              const PP_EncryptedBlockInfo* encrypted_block_info) {
    289   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    290   if (!dispatcher) {
    291     NOTREACHED();
    292     return;
    293   }
    294 
    295   PPPDecryptor_Buffer buffer;
    296   if (!InitializePppDecryptorBuffer(instance,
    297                                     dispatcher,
    298                                     encrypted_block,
    299                                     &buffer)) {
    300     NOTREACHED();
    301     return;
    302   }
    303 
    304   std::string serialized_block_info;
    305   if (!SerializeBlockInfo(*encrypted_block_info, &serialized_block_info)) {
    306     NOTREACHED();
    307     return;
    308   }
    309 
    310   // PluginResourceTracker in the plugin process assumes that resources that it
    311   // tracks have been addrefed on behalf of the plugin at the renderer side. So
    312   // we explicitly do it for |encryped_block| here.
    313   PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(encrypted_block);
    314 
    315   dispatcher->Send(
    316       new PpapiMsg_PPPContentDecryptor_Decrypt(
    317           API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    318           instance,
    319           buffer,
    320           serialized_block_info));
    321 }
    322 
    323 void InitializeAudioDecoder(
    324     PP_Instance instance,
    325     const PP_AudioDecoderConfig* decoder_config,
    326     PP_Resource extra_data_buffer) {
    327   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    328   if (!dispatcher) {
    329     NOTREACHED();
    330     return;
    331   }
    332 
    333   std::string serialized_decoder_config;
    334   if (!SerializeBlockInfo(*decoder_config, &serialized_decoder_config)) {
    335     NOTREACHED();
    336     return;
    337   }
    338 
    339   PPPDecryptor_Buffer buffer;
    340   if (!InitializePppDecryptorBuffer(instance,
    341                                     dispatcher,
    342                                     extra_data_buffer,
    343                                     &buffer)) {
    344     NOTREACHED();
    345     return;
    346   }
    347 
    348   // PluginResourceTracker in the plugin process assumes that resources that it
    349   // tracks have been addrefed on behalf of the plugin at the renderer side. So
    350   // we explicitly do it for |extra_data_buffer| here.
    351   PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(extra_data_buffer);
    352 
    353   dispatcher->Send(
    354       new PpapiMsg_PPPContentDecryptor_InitializeAudioDecoder(
    355           API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    356           instance,
    357           serialized_decoder_config,
    358           buffer));
    359 }
    360 
    361 void InitializeVideoDecoder(
    362     PP_Instance instance,
    363     const PP_VideoDecoderConfig* decoder_config,
    364     PP_Resource extra_data_buffer) {
    365   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    366   if (!dispatcher) {
    367     NOTREACHED();
    368     return;
    369   }
    370 
    371   std::string serialized_decoder_config;
    372   if (!SerializeBlockInfo(*decoder_config, &serialized_decoder_config)) {
    373     NOTREACHED();
    374     return;
    375   }
    376 
    377   PPPDecryptor_Buffer buffer;
    378   if (!InitializePppDecryptorBuffer(instance,
    379                                     dispatcher,
    380                                     extra_data_buffer,
    381                                     &buffer)) {
    382     NOTREACHED();
    383     return;
    384   }
    385 
    386   // PluginResourceTracker in the plugin process assumes that resources that it
    387   // tracks have been addrefed on behalf of the plugin at the renderer side. So
    388   // we explicitly do it for |extra_data_buffer| here.
    389   PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(extra_data_buffer);
    390 
    391   dispatcher->Send(
    392       new PpapiMsg_PPPContentDecryptor_InitializeVideoDecoder(
    393           API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    394           instance,
    395           serialized_decoder_config,
    396           buffer));
    397 }
    398 
    399 
    400 void DeinitializeDecoder(PP_Instance instance,
    401                          PP_DecryptorStreamType decoder_type,
    402                          uint32_t request_id) {
    403   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    404   if (!dispatcher) {
    405     NOTREACHED();
    406     return;
    407   }
    408 
    409   dispatcher->Send(
    410       new PpapiMsg_PPPContentDecryptor_DeinitializeDecoder(
    411           API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    412           instance,
    413           decoder_type,
    414           request_id));
    415 }
    416 
    417 void ResetDecoder(PP_Instance instance,
    418                   PP_DecryptorStreamType decoder_type,
    419                   uint32_t request_id) {
    420   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    421   if (!dispatcher) {
    422     NOTREACHED();
    423     return;
    424   }
    425 
    426   dispatcher->Send(
    427       new PpapiMsg_PPPContentDecryptor_ResetDecoder(
    428           API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    429           instance,
    430           decoder_type,
    431           request_id));
    432 }
    433 
    434 void DecryptAndDecode(PP_Instance instance,
    435                       PP_DecryptorStreamType decoder_type,
    436                       PP_Resource encrypted_buffer,
    437                       const PP_EncryptedBlockInfo* encrypted_block_info) {
    438   HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
    439   if (!dispatcher) {
    440     NOTREACHED();
    441     return;
    442   }
    443 
    444   PPPDecryptor_Buffer buffer;
    445   if (!InitializePppDecryptorBuffer(instance,
    446                                     dispatcher,
    447                                     encrypted_buffer,
    448                                     &buffer)) {
    449     NOTREACHED();
    450     return;
    451   }
    452 
    453   std::string serialized_block_info;
    454   if (!SerializeBlockInfo(*encrypted_block_info, &serialized_block_info)) {
    455     NOTREACHED();
    456     return;
    457   }
    458 
    459   // PluginResourceTracker in the plugin process assumes that resources that it
    460   // tracks have been addrefed on behalf of the plugin at the renderer side. So
    461   // we explicitly do it for |encrypted_buffer| here.
    462   PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(encrypted_buffer);
    463 
    464   dispatcher->Send(
    465       new PpapiMsg_PPPContentDecryptor_DecryptAndDecode(
    466           API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
    467           instance,
    468           decoder_type,
    469           buffer,
    470           serialized_block_info));
    471 }
    472 
    473 static const PPP_ContentDecryptor_Private content_decryptor_interface = {
    474     &Initialize,
    475     &SetServerCertificate,
    476     &CreateSession,
    477     &LoadSession,
    478     &UpdateSession,
    479     &CloseSession,
    480     &RemoveSession,
    481     &GetUsableKeyIds,
    482     &Decrypt,
    483     &InitializeAudioDecoder,
    484     &InitializeVideoDecoder,
    485     &DeinitializeDecoder,
    486     &ResetDecoder,
    487     &DecryptAndDecode};
    488 
    489 }  // namespace
    490 
    491 PPP_ContentDecryptor_Private_Proxy::PPP_ContentDecryptor_Private_Proxy(
    492     Dispatcher* dispatcher)
    493     : InterfaceProxy(dispatcher),
    494       ppp_decryptor_impl_(NULL) {
    495   if (dispatcher->IsPlugin()) {
    496     ppp_decryptor_impl_ = static_cast<const PPP_ContentDecryptor_Private*>(
    497         dispatcher->local_get_interface()(
    498             PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE));
    499   }
    500 }
    501 
    502 PPP_ContentDecryptor_Private_Proxy::~PPP_ContentDecryptor_Private_Proxy() {
    503 }
    504 
    505 // static
    506 const PPP_ContentDecryptor_Private*
    507     PPP_ContentDecryptor_Private_Proxy::GetProxyInterface() {
    508   return &content_decryptor_interface;
    509 }
    510 
    511 bool PPP_ContentDecryptor_Private_Proxy::OnMessageReceived(
    512     const IPC::Message& msg) {
    513   if (!dispatcher()->IsPlugin())
    514     return false;  // These are only valid from host->plugin.
    515                    // Don't allow the plugin to send these to the host.
    516 
    517   bool handled = true;
    518   IPC_BEGIN_MESSAGE_MAP(PPP_ContentDecryptor_Private_Proxy, msg)
    519     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_Initialize,
    520                         OnMsgInitialize)
    521     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_SetServerCertificate,
    522                         OnMsgSetServerCertificate)
    523     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_CreateSession,
    524                         OnMsgCreateSession)
    525     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_LoadSession,
    526                         OnMsgLoadSession)
    527     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_UpdateSession,
    528                         OnMsgUpdateSession)
    529     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_CloseSession,
    530                         OnMsgCloseSession)
    531     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_RemoveSession,
    532                         OnMsgRemoveSession)
    533     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_GetUsableKeyIds,
    534                         OnMsgGetUsableKeyIds)
    535     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_Decrypt,
    536                         OnMsgDecrypt)
    537     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_InitializeAudioDecoder,
    538                         OnMsgInitializeAudioDecoder)
    539     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_InitializeVideoDecoder,
    540                         OnMsgInitializeVideoDecoder)
    541     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_DeinitializeDecoder,
    542                         OnMsgDeinitializeDecoder)
    543     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_ResetDecoder,
    544                         OnMsgResetDecoder)
    545     IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_DecryptAndDecode,
    546                         OnMsgDecryptAndDecode)
    547     IPC_MESSAGE_UNHANDLED(handled = false)
    548   IPC_END_MESSAGE_MAP()
    549   DCHECK(handled);
    550   return handled;
    551 }
    552 
    553 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitialize(
    554     PP_Instance instance,
    555     SerializedVarReceiveInput key_system) {
    556   if (ppp_decryptor_impl_) {
    557     CallWhileUnlocked(
    558         ppp_decryptor_impl_->Initialize,
    559         instance,
    560         ExtractReceivedVarAndAddRef(dispatcher(), &key_system));
    561   }
    562 }
    563 
    564 void PPP_ContentDecryptor_Private_Proxy::OnMsgSetServerCertificate(
    565     PP_Instance instance,
    566     uint32_t promise_id,
    567     std::vector<uint8_t> server_certificate) {
    568   if (server_certificate.size() < media::limits::kMinCertificateLength ||
    569       server_certificate.size() > media::limits::kMaxCertificateLength) {
    570     NOTREACHED();
    571     return;
    572   }
    573 
    574   if (ppp_decryptor_impl_) {
    575     ScopedPPVar server_certificate_var(
    576         ScopedPPVar::PassRef(),
    577         PpapiGlobals::Get()
    578             ->GetVarTracker()
    579             ->MakeArrayBufferPPVar(server_certificate.size(),
    580                                    &server_certificate[0]));
    581     CallWhileUnlocked(ppp_decryptor_impl_->SetServerCertificate,
    582                       instance,
    583                       promise_id,
    584                       server_certificate_var.get());
    585   }
    586 }
    587 
    588 void PPP_ContentDecryptor_Private_Proxy::OnMsgCreateSession(
    589     PP_Instance instance,
    590     uint32_t promise_id,
    591     SerializedVarReceiveInput init_data_type,
    592     SerializedVarReceiveInput init_data,
    593     PP_SessionType session_type) {
    594   if (ppp_decryptor_impl_) {
    595     CallWhileUnlocked(
    596         ppp_decryptor_impl_->CreateSession,
    597         instance,
    598         promise_id,
    599         ExtractReceivedVarAndAddRef(dispatcher(), &init_data_type),
    600         ExtractReceivedVarAndAddRef(dispatcher(), &init_data),
    601         session_type);
    602   }
    603 }
    604 
    605 void PPP_ContentDecryptor_Private_Proxy::OnMsgLoadSession(
    606     PP_Instance instance,
    607     uint32_t promise_id,
    608     SerializedVarReceiveInput web_session_id) {
    609   if (ppp_decryptor_impl_) {
    610     CallWhileUnlocked(
    611         ppp_decryptor_impl_->LoadSession,
    612         instance,
    613         promise_id,
    614         ExtractReceivedVarAndAddRef(dispatcher(), &web_session_id));
    615   }
    616 }
    617 
    618 void PPP_ContentDecryptor_Private_Proxy::OnMsgUpdateSession(
    619     PP_Instance instance,
    620     uint32_t promise_id,
    621     SerializedVarReceiveInput web_session_id,
    622     SerializedVarReceiveInput response) {
    623   if (ppp_decryptor_impl_) {
    624     CallWhileUnlocked(
    625         ppp_decryptor_impl_->UpdateSession,
    626         instance,
    627         promise_id,
    628         ExtractReceivedVarAndAddRef(dispatcher(), &web_session_id),
    629         ExtractReceivedVarAndAddRef(dispatcher(), &response));
    630   }
    631 }
    632 
    633 void PPP_ContentDecryptor_Private_Proxy::OnMsgCloseSession(
    634     PP_Instance instance,
    635     uint32_t promise_id,
    636     const std::string& web_session_id) {
    637   if (ppp_decryptor_impl_) {
    638     ScopedPPVar web_session_id_var(ScopedPPVar::PassRef(),
    639                                    StringVar::StringToPPVar(web_session_id));
    640     CallWhileUnlocked(ppp_decryptor_impl_->CloseSession,
    641                       instance,
    642                       promise_id,
    643                       web_session_id_var.get());
    644   }
    645 }
    646 
    647 void PPP_ContentDecryptor_Private_Proxy::OnMsgRemoveSession(
    648     PP_Instance instance,
    649     uint32_t promise_id,
    650     const std::string& web_session_id) {
    651   if (ppp_decryptor_impl_) {
    652     ScopedPPVar web_session_id_var(ScopedPPVar::PassRef(),
    653                                    StringVar::StringToPPVar(web_session_id));
    654     CallWhileUnlocked(ppp_decryptor_impl_->RemoveSession,
    655                       instance,
    656                       promise_id,
    657                       web_session_id_var.get());
    658   }
    659 }
    660 
    661 void PPP_ContentDecryptor_Private_Proxy::OnMsgGetUsableKeyIds(
    662     PP_Instance instance,
    663     uint32_t promise_id,
    664     const std::string& web_session_id) {
    665   if (ppp_decryptor_impl_) {
    666     ScopedPPVar web_session_id_var(ScopedPPVar::PassRef(),
    667                                    StringVar::StringToPPVar(web_session_id));
    668     CallWhileUnlocked(ppp_decryptor_impl_->GetUsableKeyIds,
    669                       instance,
    670                       promise_id,
    671                       web_session_id_var.get());
    672   }
    673 }
    674 
    675 void PPP_ContentDecryptor_Private_Proxy::OnMsgDecrypt(
    676     PP_Instance instance,
    677     const PPPDecryptor_Buffer& encrypted_buffer,
    678     const std::string& serialized_block_info) {
    679   ScopedPPResource plugin_resource(
    680       ScopedPPResource::PassRef(),
    681       PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource,
    682                                          encrypted_buffer.handle,
    683                                          encrypted_buffer.size));
    684   if (ppp_decryptor_impl_) {
    685     PP_EncryptedBlockInfo block_info;
    686     if (!DeserializeBlockInfo(serialized_block_info, &block_info))
    687       return;
    688     CallWhileUnlocked(ppp_decryptor_impl_->Decrypt,
    689                       instance,
    690                       plugin_resource.get(),
    691                       &block_info);
    692   }
    693 }
    694 
    695 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitializeAudioDecoder(
    696     PP_Instance instance,
    697     const std::string& serialized_decoder_config,
    698     const PPPDecryptor_Buffer& extra_data_buffer) {
    699   ScopedPPResource plugin_resource;
    700   if (extra_data_buffer.size > 0) {
    701     plugin_resource = ScopedPPResource(
    702         ScopedPPResource::PassRef(),
    703         PPB_Buffer_Proxy::AddProxyResource(extra_data_buffer.resource,
    704                                            extra_data_buffer.handle,
    705                                            extra_data_buffer.size));
    706   }
    707 
    708   PP_AudioDecoderConfig decoder_config;
    709   if (!DeserializeBlockInfo(serialized_decoder_config, &decoder_config))
    710       return;
    711 
    712   if (ppp_decryptor_impl_) {
    713     CallWhileUnlocked(
    714         ppp_decryptor_impl_->InitializeAudioDecoder,
    715         instance,
    716         &decoder_config,
    717         plugin_resource.get());
    718   }
    719 }
    720 
    721 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitializeVideoDecoder(
    722     PP_Instance instance,
    723     const std::string& serialized_decoder_config,
    724     const PPPDecryptor_Buffer& extra_data_buffer) {
    725   ScopedPPResource plugin_resource;
    726   if (extra_data_buffer.resource.host_resource() != 0) {
    727     plugin_resource = ScopedPPResource(
    728         ScopedPPResource::PassRef(),
    729         PPB_Buffer_Proxy::AddProxyResource(extra_data_buffer.resource,
    730                                            extra_data_buffer.handle,
    731                                            extra_data_buffer.size));
    732   }
    733 
    734   PP_VideoDecoderConfig decoder_config;
    735   if (!DeserializeBlockInfo(serialized_decoder_config, &decoder_config))
    736       return;
    737 
    738   if (ppp_decryptor_impl_) {
    739     CallWhileUnlocked(
    740         ppp_decryptor_impl_->InitializeVideoDecoder,
    741         instance,
    742         &decoder_config,
    743         plugin_resource.get());
    744   }
    745 }
    746 
    747 void PPP_ContentDecryptor_Private_Proxy::OnMsgDeinitializeDecoder(
    748     PP_Instance instance,
    749     PP_DecryptorStreamType decoder_type,
    750     uint32_t request_id) {
    751   if (ppp_decryptor_impl_) {
    752     CallWhileUnlocked(
    753         ppp_decryptor_impl_->DeinitializeDecoder,
    754         instance,
    755         decoder_type,
    756         request_id);
    757   }
    758 }
    759 
    760 void PPP_ContentDecryptor_Private_Proxy::OnMsgResetDecoder(
    761     PP_Instance instance,
    762     PP_DecryptorStreamType decoder_type,
    763     uint32_t request_id) {
    764   if (ppp_decryptor_impl_) {
    765     CallWhileUnlocked(
    766         ppp_decryptor_impl_->ResetDecoder,
    767         instance,
    768         decoder_type,
    769         request_id);
    770   }
    771 }
    772 
    773 void PPP_ContentDecryptor_Private_Proxy::OnMsgDecryptAndDecode(
    774     PP_Instance instance,
    775     PP_DecryptorStreamType decoder_type,
    776     const PPPDecryptor_Buffer& encrypted_buffer,
    777     const std::string& serialized_block_info) {
    778   ScopedPPResource plugin_resource;
    779   if (encrypted_buffer.resource.host_resource() != 0) {
    780     plugin_resource = ScopedPPResource(
    781         ScopedPPResource::PassRef(),
    782         PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource,
    783                                            encrypted_buffer.handle,
    784                                            encrypted_buffer.size));
    785   }
    786 
    787   if (ppp_decryptor_impl_) {
    788     PP_EncryptedBlockInfo block_info;
    789     if (!DeserializeBlockInfo(serialized_block_info, &block_info))
    790       return;
    791     CallWhileUnlocked(
    792         ppp_decryptor_impl_->DecryptAndDecode,
    793         instance,
    794         decoder_type,
    795         plugin_resource.get(),
    796         &block_info);
    797   }
    798 }
    799 
    800 }  // namespace proxy
    801 }  // namespace ppapi
    802