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
Initialize(PP_Instance instance,PP_Var key_system_arg)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
SetServerCertificate(PP_Instance instance,uint32_t promise_id,PP_Var server_certificate_arg)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
CreateSession(PP_Instance instance,uint32_t promise_id,PP_Var init_data_type_arg,PP_Var init_data_arg,PP_SessionType session_type)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
LoadSession(PP_Instance instance,uint32_t promise_id,PP_Var web_session_id_arg)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
UpdateSession(PP_Instance instance,uint32_t promise_id,PP_Var web_session_id_arg,PP_Var response_arg)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
CloseSession(PP_Instance instance,uint32_t promise_id,PP_Var web_session_id_arg)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
RemoveSession(PP_Instance instance,uint32_t promise_id,PP_Var web_session_id_arg)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
GetUsableKeyIds(PP_Instance instance,uint32_t promise_id,PP_Var web_session_id_arg)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
Decrypt(PP_Instance instance,PP_Resource encrypted_resource,const PP_EncryptedBlockInfo * encrypted_block_info)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
InitializeAudioDecoder(PP_Instance instance,const PP_AudioDecoderConfig * decoder_config,PP_Resource extra_data_resource)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
InitializeVideoDecoder(PP_Instance instance,const PP_VideoDecoderConfig * decoder_config,PP_Resource extra_data_resource)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
DeinitializeDecoder(PP_Instance instance,PP_DecryptorStreamType decoder_type,uint32_t request_id)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
ResetDecoder(PP_Instance instance,PP_DecryptorStreamType decoder_type,uint32_t request_id)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
DecryptAndDecode(PP_Instance instance,PP_DecryptorStreamType decoder_type,PP_Resource encrypted_resource,const PP_EncryptedBlockInfo * encrypted_block_info)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
interface_name()274 template <> const char* interface_name<PPB_ContentDecryptor_Private>() {
275 return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE;
276 }
277
278 } // namespace
279
ContentDecryptor_Private(Instance * instance)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
~ContentDecryptor_Private()287 ContentDecryptor_Private::~ContentDecryptor_Private() {
288 Instance::RemovePerInstanceObject(associated_instance_,
289 kPPPContentDecryptorInterface,
290 this);
291 }
292
PromiseResolved(uint32_t promise_id)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
PromiseResolvedWithSession(uint32_t promise_id,const std::string & web_session_id)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
PromiseResolvedWithKeyIds(uint32_t promise_id,const std::vector<std::vector<uint8_t>> & key_ids)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
PromiseRejected(uint32_t promise_id,PP_CdmExceptionCode exception_code,uint32_t system_code,const std::string & error_description)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
SessionMessage(const std::string & web_session_id,pp::VarArrayBuffer message,const std::string & destination_url)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
SessionKeysChange(const std::string & web_session_id,bool has_additional_usable_key)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
SessionExpirationChange(const std::string & web_session_id,PP_Time new_expiry_time)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
SessionReady(const std::string & web_session_id)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
SessionClosed(const std::string & web_session_id)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
SessionError(const std::string & web_session_id,PP_CdmExceptionCode exception_code,uint32_t system_code,const std::string & error_description)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
DeliverBlock(pp::Buffer_Dev decrypted_block,const PP_DecryptedBlockInfo & decrypted_block_info)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
DecoderInitializeDone(PP_DecryptorStreamType decoder_type,uint32_t request_id,bool success)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
DecoderDeinitializeDone(PP_DecryptorStreamType decoder_type,uint32_t request_id)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
DecoderResetDone(PP_DecryptorStreamType decoder_type,uint32_t request_id)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
DeliverFrame(pp::Buffer_Dev decrypted_frame,const PP_DecryptedFrameInfo & decrypted_frame_info)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
DeliverSamples(pp::Buffer_Dev audio_frames,const PP_DecryptedSampleInfo & decrypted_sample_info)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