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
,
28 PP_Var key_system_arg
,
29 PP_Bool allow_distinctive_identifier
,
30 PP_Bool allow_persistent_state
) {
32 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
36 pp::Var
key_system_var(pp::PASS_REF
, key_system_arg
);
37 if (!key_system_var
.is_string())
40 static_cast<ContentDecryptor_Private
*>(object
)->Initialize(
41 key_system_var
.AsString(),
42 PP_ToBool(allow_distinctive_identifier
),
43 PP_ToBool(allow_persistent_state
));
46 void SetServerCertificate(PP_Instance instance
,
48 PP_Var server_certificate_arg
) {
50 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
54 pp::Var
server_certificate_var(server_certificate_arg
);
55 if (!server_certificate_var
.is_array_buffer())
57 pp::VarArrayBuffer
server_certificate(server_certificate_var
);
59 static_cast<ContentDecryptor_Private
*>(object
)
60 ->SetServerCertificate(promise_id
, server_certificate
);
63 void CreateSessionAndGenerateRequest(PP_Instance instance
,
65 PP_SessionType session_type
,
66 PP_InitDataType init_data_type
,
67 PP_Var init_data_arg
) {
69 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
73 pp::Var
init_data_var(pp::PASS_REF
, init_data_arg
);
74 if (!init_data_var
.is_array_buffer())
76 pp::VarArrayBuffer
init_data_array_buffer(init_data_var
);
78 static_cast<ContentDecryptor_Private
*>(object
)
79 ->CreateSessionAndGenerateRequest(promise_id
, session_type
,
80 init_data_type
, init_data_array_buffer
);
83 void LoadSession(PP_Instance instance
,
85 PP_SessionType session_type
,
86 PP_Var session_id_arg
) {
88 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
92 pp::Var
session_id_var(session_id_arg
);
93 if (!session_id_var
.is_string())
96 static_cast<ContentDecryptor_Private
*>(object
)
97 ->LoadSession(promise_id
, session_type
, session_id_var
.AsString());
100 void UpdateSession(PP_Instance instance
,
102 PP_Var session_id_arg
,
103 PP_Var response_arg
) {
105 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
109 pp::Var
session_id_var(session_id_arg
);
110 if (!session_id_var
.is_string())
113 pp::Var
response_var(response_arg
);
114 if (!response_var
.is_array_buffer())
116 pp::VarArrayBuffer
response(response_var
);
118 static_cast<ContentDecryptor_Private
*>(object
)
119 ->UpdateSession(promise_id
, session_id_var
.AsString(), response
);
122 void CloseSession(PP_Instance instance
,
124 PP_Var session_id_arg
) {
126 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
130 pp::Var
session_id_var(session_id_arg
);
131 if (!session_id_var
.is_string())
134 static_cast<ContentDecryptor_Private
*>(object
)
135 ->CloseSession(promise_id
, session_id_var
.AsString());
138 void RemoveSession(PP_Instance instance
,
140 PP_Var session_id_arg
) {
142 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
146 pp::Var
session_id_var(session_id_arg
);
147 if (!session_id_var
.is_string())
150 static_cast<ContentDecryptor_Private
*>(object
)
151 ->RemoveSession(promise_id
, session_id_var
.AsString());
154 void Decrypt(PP_Instance instance
,
155 PP_Resource encrypted_resource
,
156 const PP_EncryptedBlockInfo
* encrypted_block_info
) {
157 pp::Buffer_Dev
encrypted_block(encrypted_resource
);
160 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
164 static_cast<ContentDecryptor_Private
*>(object
)->Decrypt(
166 *encrypted_block_info
);
169 void InitializeAudioDecoder(
170 PP_Instance instance
,
171 const PP_AudioDecoderConfig
* decoder_config
,
172 PP_Resource extra_data_resource
) {
173 pp::Buffer_Dev
extra_data_buffer(extra_data_resource
);
176 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
180 static_cast<ContentDecryptor_Private
*>(object
)->InitializeAudioDecoder(
185 void InitializeVideoDecoder(
186 PP_Instance instance
,
187 const PP_VideoDecoderConfig
* decoder_config
,
188 PP_Resource extra_data_resource
) {
189 pp::Buffer_Dev
extra_data_buffer(extra_data_resource
);
192 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
196 static_cast<ContentDecryptor_Private
*>(object
)->InitializeVideoDecoder(
201 void DeinitializeDecoder(PP_Instance instance
,
202 PP_DecryptorStreamType decoder_type
,
203 uint32_t request_id
) {
205 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
208 static_cast<ContentDecryptor_Private
*>(object
)->DeinitializeDecoder(
213 void ResetDecoder(PP_Instance instance
,
214 PP_DecryptorStreamType decoder_type
,
215 uint32_t request_id
) {
217 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
220 static_cast<ContentDecryptor_Private
*>(object
)->ResetDecoder(decoder_type
,
224 void DecryptAndDecode(PP_Instance instance
,
225 PP_DecryptorStreamType decoder_type
,
226 PP_Resource encrypted_resource
,
227 const PP_EncryptedBlockInfo
* encrypted_block_info
) {
228 pp::Buffer_Dev
encrypted_buffer(encrypted_resource
);
231 Instance::GetPerInstanceObject(instance
, kPPPContentDecryptorInterface
);
235 static_cast<ContentDecryptor_Private
*>(object
)->DecryptAndDecode(
238 *encrypted_block_info
);
241 const PPP_ContentDecryptor_Private ppp_content_decryptor
= {
243 &SetServerCertificate
,
244 &CreateSessionAndGenerateRequest
,
250 &InitializeAudioDecoder
,
251 &InitializeVideoDecoder
,
252 &DeinitializeDecoder
,
256 template <> const char* interface_name
<PPB_ContentDecryptor_Private
>() {
257 return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE
;
262 ContentDecryptor_Private::ContentDecryptor_Private(Instance
* instance
)
263 : associated_instance_(instance
) {
264 Module::Get()->AddPluginInterface(kPPPContentDecryptorInterface
,
265 &ppp_content_decryptor
);
266 instance
->AddPerInstanceObject(kPPPContentDecryptorInterface
, this);
269 ContentDecryptor_Private::~ContentDecryptor_Private() {
270 Instance::RemovePerInstanceObject(associated_instance_
,
271 kPPPContentDecryptorInterface
,
275 void ContentDecryptor_Private::PromiseResolved(uint32_t promise_id
) {
276 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
277 get_interface
<PPB_ContentDecryptor_Private
>()->PromiseResolved(
278 associated_instance_
.pp_instance(), promise_id
);
282 void ContentDecryptor_Private::PromiseResolvedWithSession(
284 const std::string
& session_id
) {
285 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
286 pp::Var
session_id_var(session_id
);
287 get_interface
<PPB_ContentDecryptor_Private
>()->PromiseResolvedWithSession(
288 associated_instance_
.pp_instance(), promise_id
,
289 session_id_var
.pp_var());
293 void ContentDecryptor_Private::PromiseRejected(
295 PP_CdmExceptionCode exception_code
,
296 uint32_t system_code
,
297 const std::string
& error_description
) {
298 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
299 pp::Var
error_description_var(error_description
);
300 get_interface
<PPB_ContentDecryptor_Private
>()->PromiseRejected(
301 associated_instance_
.pp_instance(),
305 error_description_var
.pp_var());
309 void ContentDecryptor_Private::SessionMessage(
310 const std::string
& session_id
,
311 PP_CdmMessageType message_type
,
312 pp::VarArrayBuffer message
,
313 const std::string
& legacy_destination_url
) {
314 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
315 pp::Var
session_id_var(session_id
);
316 pp::Var
legacy_destination_url_var(legacy_destination_url
);
317 get_interface
<PPB_ContentDecryptor_Private
>()->SessionMessage(
318 associated_instance_
.pp_instance(), session_id_var
.pp_var(),
319 message_type
, message
.pp_var(), legacy_destination_url_var
.pp_var());
323 void ContentDecryptor_Private::SessionKeysChange(
324 const std::string
& session_id
,
325 bool has_additional_usable_key
,
326 const std::vector
<PP_KeyInformation
>& key_information
) {
327 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
328 pp::Var
session_id_var(session_id
);
329 get_interface
<PPB_ContentDecryptor_Private
>()->SessionKeysChange(
330 associated_instance_
.pp_instance(), session_id_var
.pp_var(),
331 PP_FromBool(has_additional_usable_key
),
332 static_cast<uint32_t>(key_information
.size()),
333 key_information
.empty() ? NULL
: &key_information
[0]);
337 void ContentDecryptor_Private::SessionExpirationChange(
338 const std::string
& session_id
,
339 PP_Time new_expiry_time
) {
340 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
341 pp::Var
session_id_var(session_id
);
342 get_interface
<PPB_ContentDecryptor_Private
>()->SessionExpirationChange(
343 associated_instance_
.pp_instance(), session_id_var
.pp_var(),
348 void ContentDecryptor_Private::SessionClosed(const std::string
& session_id
) {
349 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
350 pp::Var
session_id_var(session_id
);
351 get_interface
<PPB_ContentDecryptor_Private
>()->SessionClosed(
352 associated_instance_
.pp_instance(), session_id_var
.pp_var());
356 void ContentDecryptor_Private::LegacySessionError(
357 const std::string
& session_id
,
358 PP_CdmExceptionCode exception_code
,
359 uint32_t system_code
,
360 const std::string
& error_description
) {
361 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
362 pp::Var
session_id_var(session_id
);
363 pp::Var
error_description_var(error_description
);
364 get_interface
<PPB_ContentDecryptor_Private
>()->LegacySessionError(
365 associated_instance_
.pp_instance(), session_id_var
.pp_var(),
366 exception_code
, system_code
, error_description_var
.pp_var());
370 void ContentDecryptor_Private::DeliverBlock(
371 pp::Buffer_Dev decrypted_block
,
372 const PP_DecryptedBlockInfo
& decrypted_block_info
) {
373 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
374 get_interface
<PPB_ContentDecryptor_Private
>()->DeliverBlock(
375 associated_instance_
.pp_instance(),
376 decrypted_block
.pp_resource(),
377 &decrypted_block_info
);
381 void ContentDecryptor_Private::DecoderInitializeDone(
382 PP_DecryptorStreamType decoder_type
,
385 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
386 get_interface
<PPB_ContentDecryptor_Private
>()->DecoderInitializeDone(
387 associated_instance_
.pp_instance(),
390 PP_FromBool(success
));
394 void ContentDecryptor_Private::DecoderDeinitializeDone(
395 PP_DecryptorStreamType decoder_type
,
396 uint32_t request_id
) {
397 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
398 get_interface
<PPB_ContentDecryptor_Private
>()->DecoderDeinitializeDone(
399 associated_instance_
.pp_instance(),
405 void ContentDecryptor_Private::DecoderResetDone(
406 PP_DecryptorStreamType decoder_type
,
407 uint32_t request_id
) {
408 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
409 get_interface
<PPB_ContentDecryptor_Private
>()->DecoderResetDone(
410 associated_instance_
.pp_instance(),
416 void ContentDecryptor_Private::DeliverFrame(
417 pp::Buffer_Dev decrypted_frame
,
418 const PP_DecryptedFrameInfo
& decrypted_frame_info
) {
419 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
420 get_interface
<PPB_ContentDecryptor_Private
>()->DeliverFrame(
421 associated_instance_
.pp_instance(),
422 decrypted_frame
.pp_resource(),
423 &decrypted_frame_info
);
427 void ContentDecryptor_Private::DeliverSamples(
428 pp::Buffer_Dev audio_frames
,
429 const PP_DecryptedSampleInfo
& decrypted_sample_info
) {
430 if (has_interface
<PPB_ContentDecryptor_Private
>()) {
431 get_interface
<PPB_ContentDecryptor_Private
>()->DeliverSamples(
432 associated_instance_
.pp_instance(),
433 audio_frames
.pp_resource(),
434 &decrypted_sample_info
);