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.
5 #include "ppapi/cpp/private/content_decryptor_private.h"
7 #include <cstring> // memcpy
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"
24 static const char kPPPContentDecryptorInterface
[] =
25 PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE
;
27 void Initialize(PP_Instance instance
,
29 PP_Var key_system_arg
,
30 PP_Bool allow_distinctive_identifier
,
31 PP_Bool allow_persistent_state
) {
33 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
37 pp::Var
key_system_var(pp::PASS_REF
, key_system_arg
);
38 if (!key_system_var
.is_string())
41 static_cast<ContentDecryptor_Private
*>(object
)
42 ->Initialize(promise_id
, key_system_var
.AsString(),
43 PP_ToBool(allow_distinctive_identifier
),
44 PP_ToBool(allow_persistent_state
));
47 void SetServerCertificate(PP_Instance instance
,
49 PP_Var server_certificate_arg
) {
51 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
55 pp::Var
server_certificate_var(server_certificate_arg
);
56 if (!server_certificate_var
.is_array_buffer())
58 pp::VarArrayBuffer
server_certificate(server_certificate_var
);
60 static_cast<ContentDecryptor_Private
*>(object
)
61 ->SetServerCertificate(promise_id
, server_certificate
);
64 void CreateSessionAndGenerateRequest(PP_Instance instance
,
66 PP_SessionType session_type
,
67 PP_InitDataType init_data_type
,
68 PP_Var init_data_arg
) {
70 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
74 pp::Var
init_data_var(pp::PASS_REF
, init_data_arg
);
75 if (!init_data_var
.is_array_buffer())
77 pp::VarArrayBuffer
init_data_array_buffer(init_data_var
);
79 static_cast<ContentDecryptor_Private
*>(object
)
80 ->CreateSessionAndGenerateRequest(promise_id
, session_type
,
81 init_data_type
, init_data_array_buffer
);
84 void LoadSession(PP_Instance instance
,
86 PP_SessionType session_type
,
87 PP_Var session_id_arg
) {
89 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
93 pp::Var
session_id_var(session_id_arg
);
94 if (!session_id_var
.is_string())
97 static_cast<ContentDecryptor_Private
*>(object
)
98 ->LoadSession(promise_id
, session_type
, session_id_var
.AsString());
101 void UpdateSession(PP_Instance instance
,
103 PP_Var session_id_arg
,
104 PP_Var response_arg
) {
106 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
110 pp::Var
session_id_var(session_id_arg
);
111 if (!session_id_var
.is_string())
114 pp::Var
response_var(response_arg
);
115 if (!response_var
.is_array_buffer())
117 pp::VarArrayBuffer
response(response_var
);
119 static_cast<ContentDecryptor_Private
*>(object
)
120 ->UpdateSession(promise_id
, session_id_var
.AsString(), response
);
123 void CloseSession(PP_Instance instance
,
125 PP_Var session_id_arg
) {
127 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
131 pp::Var
session_id_var(session_id_arg
);
132 if (!session_id_var
.is_string())
135 static_cast<ContentDecryptor_Private
*>(object
)
136 ->CloseSession(promise_id
, session_id_var
.AsString());
139 void RemoveSession(PP_Instance instance
,
141 PP_Var session_id_arg
) {
143 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
147 pp::Var
session_id_var(session_id_arg
);
148 if (!session_id_var
.is_string())
151 static_cast<ContentDecryptor_Private
*>(object
)
152 ->RemoveSession(promise_id
, session_id_var
.AsString());
155 void Decrypt(PP_Instance instance
,
156 PP_Resource encrypted_resource
,
157 const PP_EncryptedBlockInfo
* encrypted_block_info
) {
158 pp::Buffer_Dev
encrypted_block(encrypted_resource
);
161 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
165 static_cast<ContentDecryptor_Private
*>(object
)->Decrypt(
167 *encrypted_block_info
);
170 void InitializeAudioDecoder(
171 PP_Instance instance
,
172 const PP_AudioDecoderConfig
* decoder_config
,
173 PP_Resource extra_data_resource
) {
174 pp::Buffer_Dev
extra_data_buffer(extra_data_resource
);
177 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
181 static_cast<ContentDecryptor_Private
*>(object
)->InitializeAudioDecoder(
186 void InitializeVideoDecoder(
187 PP_Instance instance
,
188 const PP_VideoDecoderConfig
* decoder_config
,
189 PP_Resource extra_data_resource
) {
190 pp::Buffer_Dev
extra_data_buffer(extra_data_resource
);
193 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
197 static_cast<ContentDecryptor_Private
*>(object
)->InitializeVideoDecoder(
202 void DeinitializeDecoder(PP_Instance instance
,
203 PP_DecryptorStreamType decoder_type
,
204 uint32_t request_id
) {
206 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
209 static_cast<ContentDecryptor_Private
*>(object
)->DeinitializeDecoder(
214 void ResetDecoder(PP_Instance instance
,
215 PP_DecryptorStreamType decoder_type
,
216 uint32_t request_id
) {
218 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
221 static_cast<ContentDecryptor_Private
*>(object
)->ResetDecoder(decoder_type
,
225 void DecryptAndDecode(PP_Instance instance
,
226 PP_DecryptorStreamType decoder_type
,
227 PP_Resource encrypted_resource
,
228 const PP_EncryptedBlockInfo
* encrypted_block_info
) {
229 pp::Buffer_Dev
encrypted_buffer(encrypted_resource
);
232 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
236 static_cast<ContentDecryptor_Private
*>(object
)->DecryptAndDecode(
239 *encrypted_block_info
);
242 const PPP_ContentDecryptor_Private ppp_content_decryptor
= {
244 &SetServerCertificate
,
245 &CreateSessionAndGenerateRequest
,
251 &InitializeAudioDecoder
,
252 &InitializeVideoDecoder
,
253 &DeinitializeDecoder
,
257 template <> const char* interface_name
<PPB_ContentDecryptor_Private
>() {
258 return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE
;
263 ContentDecryptor_Private::ContentDecryptor_Private(Instance
* instance
)
264 : associated_instance_(instance
) {
265 Module::Get()->AddPluginInterface(kPPPContentDecryptorInterface
,
266 &ppp_content_decryptor
);
267 instance
->AddPerInstanceObject(kPPPContentDecryptorInterface
, this);
270 ContentDecryptor_Private::~ContentDecryptor_Private() {
271 Instance::RemovePerInstanceObject(associated_instance_
,
272 kPPPContentDecryptorInterface
,
276 void ContentDecryptor_Private::PromiseResolved(uint32_t promise_id
) {
277 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
278 get_interface
<PPB_ContentDecryptor_Private
>()->PromiseResolved(
279 associated_instance_
.pp_instance(), promise_id
);
283 void ContentDecryptor_Private::PromiseResolvedWithSession(
285 const std::string
& session_id
) {
286 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
287 pp::Var
session_id_var(session_id
);
288 get_interface
<PPB_ContentDecryptor_Private
>()->PromiseResolvedWithSession(
289 associated_instance_
.pp_instance(), promise_id
,
290 session_id_var
.pp_var());
294 void ContentDecryptor_Private::PromiseRejected(
296 PP_CdmExceptionCode exception_code
,
297 uint32_t system_code
,
298 const std::string
& error_description
) {
299 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
300 pp::Var
error_description_var(error_description
);
301 get_interface
<PPB_ContentDecryptor_Private
>()->PromiseRejected(
302 associated_instance_
.pp_instance(),
306 error_description_var
.pp_var());
310 void ContentDecryptor_Private::SessionMessage(
311 const std::string
& session_id
,
312 PP_CdmMessageType message_type
,
313 pp::VarArrayBuffer message
,
314 const std::string
& legacy_destination_url
) {
315 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
316 pp::Var
session_id_var(session_id
);
317 pp::Var
legacy_destination_url_var(legacy_destination_url
);
318 get_interface
<PPB_ContentDecryptor_Private
>()->SessionMessage(
319 associated_instance_
.pp_instance(), session_id_var
.pp_var(),
320 message_type
, message
.pp_var(), legacy_destination_url_var
.pp_var());
324 void ContentDecryptor_Private::SessionKeysChange(
325 const std::string
& session_id
,
326 bool has_additional_usable_key
,
327 const std::vector
<PP_KeyInformation
>& key_information
) {
328 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
329 pp::Var
session_id_var(session_id
);
330 get_interface
<PPB_ContentDecryptor_Private
>()->SessionKeysChange(
331 associated_instance_
.pp_instance(), session_id_var
.pp_var(),
332 PP_FromBool(has_additional_usable_key
),
333 static_cast<uint32_t>(key_information
.size()),
334 key_information
.empty() ? NULL
: &key_information
[0]);
338 void ContentDecryptor_Private::SessionExpirationChange(
339 const std::string
& session_id
,
340 PP_Time new_expiry_time
) {
341 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
342 pp::Var
session_id_var(session_id
);
343 get_interface
<PPB_ContentDecryptor_Private
>()->SessionExpirationChange(
344 associated_instance_
.pp_instance(), session_id_var
.pp_var(),
349 void ContentDecryptor_Private::SessionClosed(const std::string
& session_id
) {
350 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
351 pp::Var
session_id_var(session_id
);
352 get_interface
<PPB_ContentDecryptor_Private
>()->SessionClosed(
353 associated_instance_
.pp_instance(), session_id_var
.pp_var());
357 void ContentDecryptor_Private::LegacySessionError(
358 const std::string
& session_id
,
359 PP_CdmExceptionCode exception_code
,
360 uint32_t system_code
,
361 const std::string
& error_description
) {
362 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
363 pp::Var
session_id_var(session_id
);
364 pp::Var
error_description_var(error_description
);
365 get_interface
<PPB_ContentDecryptor_Private
>()->LegacySessionError(
366 associated_instance_
.pp_instance(), session_id_var
.pp_var(),
367 exception_code
, system_code
, error_description_var
.pp_var());
371 void ContentDecryptor_Private::DeliverBlock(
372 pp::Buffer_Dev decrypted_block
,
373 const PP_DecryptedBlockInfo
& decrypted_block_info
) {
374 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
375 get_interface
<PPB_ContentDecryptor_Private
>()->DeliverBlock(
376 associated_instance_
.pp_instance(),
377 decrypted_block
.pp_resource(),
378 &decrypted_block_info
);
382 void ContentDecryptor_Private::DecoderInitializeDone(
383 PP_DecryptorStreamType decoder_type
,
386 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
387 get_interface
<PPB_ContentDecryptor_Private
>()->DecoderInitializeDone(
388 associated_instance_
.pp_instance(),
391 PP_FromBool(success
));
395 void ContentDecryptor_Private::DecoderDeinitializeDone(
396 PP_DecryptorStreamType decoder_type
,
397 uint32_t request_id
) {
398 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
399 get_interface
<PPB_ContentDecryptor_Private
>()->DecoderDeinitializeDone(
400 associated_instance_
.pp_instance(),
406 void ContentDecryptor_Private::DecoderResetDone(
407 PP_DecryptorStreamType decoder_type
,
408 uint32_t request_id
) {
409 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
410 get_interface
<PPB_ContentDecryptor_Private
>()->DecoderResetDone(
411 associated_instance_
.pp_instance(),
417 void ContentDecryptor_Private::DeliverFrame(
418 pp::Buffer_Dev decrypted_frame
,
419 const PP_DecryptedFrameInfo
& decrypted_frame_info
) {
420 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
421 get_interface
<PPB_ContentDecryptor_Private
>()->DeliverFrame(
422 associated_instance_
.pp_instance(),
423 decrypted_frame
.pp_resource(),
424 &decrypted_frame_info
);
428 void ContentDecryptor_Private::DeliverSamples(
429 pp::Buffer_Dev audio_frames
,
430 const PP_DecryptedSampleInfo
& decrypted_sample_info
) {
431 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
432 get_interface
<PPB_ContentDecryptor_Private
>()->DeliverSamples(
433 associated_instance_
.pp_instance(),
434 audio_frames
.pp_resource(),
435 &decrypted_sample_info
);