• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Initialize(PP_Instance instance,PP_Var key_system_arg)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 
CreateSession(PP_Instance instance,uint32_t promise_id,PP_Var init_data_type_arg,PP_Var init_data_arg,PP_SessionType session_type)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 
LoadSession(PP_Instance instance,uint32_t promise_id,PP_Var web_session_id_arg)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 
UpdateSession(PP_Instance instance,uint32_t promise_id,PP_Var web_session_id_arg,PP_Var response_arg)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 
ReleaseSession(PP_Instance instance,uint32_t promise_id,PP_Var web_session_id_arg)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 
Decrypt(PP_Instance instance,PP_Resource encrypted_resource,const PP_EncryptedBlockInfo * encrypted_block_info)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 
InitializeAudioDecoder(PP_Instance instance,const PP_AudioDecoderConfig * decoder_config,PP_Resource extra_data_resource)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 
InitializeVideoDecoder(PP_Instance instance,const PP_VideoDecoderConfig * decoder_config,PP_Resource extra_data_resource)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 
DeinitializeDecoder(PP_Instance instance,PP_DecryptorStreamType decoder_type,uint32_t request_id)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 
ResetDecoder(PP_Instance instance,PP_DecryptorStreamType decoder_type,uint32_t request_id)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 
DecryptAndDecode(PP_Instance instance,PP_DecryptorStreamType decoder_type,PP_Resource encrypted_resource,const PP_EncryptedBlockInfo * encrypted_block_info)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 
interface_name()222 template <> const char* interface_name<PPB_ContentDecryptor_Private>() {
223   return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE;
224 }
225 
226 }  // namespace
227 
ContentDecryptor_Private(Instance * instance)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 
~ContentDecryptor_Private()235 ContentDecryptor_Private::~ContentDecryptor_Private() {
236   Instance::RemovePerInstanceObject(associated_instance_,
237                                     kPPPContentDecryptorInterface,
238                                     this);
239 }
240 
PromiseResolved(uint32_t promise_id)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 
PromiseResolvedWithSession(uint32_t promise_id,const std::string & web_session_id)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 
PromiseRejected(uint32_t promise_id,PP_CdmExceptionCode exception_code,uint32_t system_code,const std::string & error_description)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 
SessionMessage(const std::string & web_session_id,pp::VarArrayBuffer message,const std::string & destination_url)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 
SessionReady(const std::string & web_session_id)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 
SessionClosed(const std::string & web_session_id)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 
SessionError(const std::string & web_session_id,PP_CdmExceptionCode exception_code,uint32_t system_code,const std::string & error_description)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 
DeliverBlock(pp::Buffer_Dev decrypted_block,const PP_DecryptedBlockInfo & decrypted_block_info)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 
DecoderInitializeDone(PP_DecryptorStreamType decoder_type,uint32_t request_id,bool success)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 
DecoderDeinitializeDone(PP_DecryptorStreamType decoder_type,uint32_t request_id)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 
DecoderResetDone(PP_DecryptorStreamType decoder_type,uint32_t request_id)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 
DeliverFrame(pp::Buffer_Dev decrypted_frame,const PP_DecryptedFrameInfo & decrypted_frame_info)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 
DeliverSamples(pp::Buffer_Dev audio_frames,const PP_DecryptedSampleInfo & decrypted_sample_info)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