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
19namespace pp {
20
21namespace {
22
23static const char kPPPContentDecryptorInterface[] =
24    PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE;
25
26void GenerateKeyRequest(PP_Instance instance,
27                        PP_Var key_system_arg,
28                        PP_Var type_arg,
29                        PP_Var init_data_arg) {
30  void* object =
31      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
32  if (!object)
33    return;
34
35  pp::Var key_system_var(pp::PASS_REF, key_system_arg);
36  if (!key_system_var.is_string())
37    return;
38
39  pp::Var type_var(pp::PASS_REF, type_arg);
40  if (!type_var.is_string())
41    return;
42
43  pp::Var init_data_var(pp::PASS_REF, init_data_arg);
44  if (!init_data_var.is_array_buffer())
45    return;
46  pp::VarArrayBuffer init_data_array_buffer(init_data_var);
47
48  static_cast<ContentDecryptor_Private*>(object)->GenerateKeyRequest(
49      key_system_var.AsString(),
50      type_var.AsString(),
51      init_data_array_buffer);
52}
53
54void AddKey(PP_Instance instance,
55            PP_Var session_id_arg,
56            PP_Var key_arg,
57            PP_Var init_data_arg) {
58  void* object =
59      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
60  if (!object)
61    return;
62
63  pp::Var session_id_var(pp::PASS_REF, session_id_arg);
64  if (!session_id_var.is_string())
65    return;
66
67  pp::Var key_var(pp::PASS_REF, key_arg);
68  if (!key_var.is_array_buffer())
69    return;
70  pp::VarArrayBuffer key(key_var);
71
72  pp::Var init_data_var(pp::PASS_REF, init_data_arg);
73  if (!init_data_var.is_array_buffer())
74    return;
75  pp::VarArrayBuffer init_data(init_data_var);
76
77
78  static_cast<ContentDecryptor_Private*>(object)->AddKey(
79      session_id_var.AsString(),
80      key,
81      init_data);
82}
83
84void CancelKeyRequest(PP_Instance instance, PP_Var session_id_arg) {
85  void* object =
86      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
87  if (!object)
88    return;
89
90  pp::Var session_id_var(pp::PASS_REF, session_id_arg);
91  if (!session_id_var.is_string())
92    return;
93
94  static_cast<ContentDecryptor_Private*>(object)->CancelKeyRequest(
95      session_id_var.AsString());
96}
97
98
99void Decrypt(PP_Instance instance,
100             PP_Resource encrypted_resource,
101             const PP_EncryptedBlockInfo* encrypted_block_info) {
102  pp::Buffer_Dev encrypted_block(encrypted_resource);
103
104  void* object =
105      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
106  if (!object)
107    return;
108
109  static_cast<ContentDecryptor_Private*>(object)->Decrypt(
110      encrypted_block,
111      *encrypted_block_info);
112}
113
114void InitializeAudioDecoder(
115    PP_Instance instance,
116    const PP_AudioDecoderConfig* decoder_config,
117    PP_Resource extra_data_resource) {
118  pp::Buffer_Dev extra_data_buffer(extra_data_resource);
119
120  void* object =
121      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
122  if (!object)
123    return;
124
125  static_cast<ContentDecryptor_Private*>(object)->InitializeAudioDecoder(
126      *decoder_config,
127      extra_data_buffer);
128}
129
130void InitializeVideoDecoder(
131    PP_Instance instance,
132    const PP_VideoDecoderConfig* decoder_config,
133    PP_Resource extra_data_resource) {
134  pp::Buffer_Dev extra_data_buffer(extra_data_resource);
135
136  void* object =
137      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
138  if (!object)
139    return;
140
141  static_cast<ContentDecryptor_Private*>(object)->InitializeVideoDecoder(
142      *decoder_config,
143      extra_data_buffer);
144}
145
146void DeinitializeDecoder(PP_Instance instance,
147                         PP_DecryptorStreamType decoder_type,
148                         uint32_t request_id) {
149  void* object =
150      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
151  if (!object)
152    return;
153  static_cast<ContentDecryptor_Private*>(object)->DeinitializeDecoder(
154      decoder_type,
155      request_id);
156}
157
158void ResetDecoder(PP_Instance instance,
159                  PP_DecryptorStreamType decoder_type,
160                  uint32_t request_id) {
161  void* object =
162      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
163  if (!object)
164    return;
165  static_cast<ContentDecryptor_Private*>(object)->ResetDecoder(decoder_type,
166                                                               request_id);
167}
168
169void DecryptAndDecode(PP_Instance instance,
170                      PP_DecryptorStreamType decoder_type,
171                      PP_Resource encrypted_resource,
172                      const PP_EncryptedBlockInfo* encrypted_block_info) {
173  pp::Buffer_Dev encrypted_buffer(encrypted_resource);
174
175  void* object =
176      Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface);
177  if (!object)
178    return;
179
180  static_cast<ContentDecryptor_Private*>(object)->DecryptAndDecode(
181      decoder_type,
182      encrypted_buffer,
183      *encrypted_block_info);
184}
185
186const PPP_ContentDecryptor_Private ppp_content_decryptor = {
187  &GenerateKeyRequest,
188  &AddKey,
189  &CancelKeyRequest,
190  &Decrypt,
191  &InitializeAudioDecoder,
192  &InitializeVideoDecoder,
193  &DeinitializeDecoder,
194  &ResetDecoder,
195  &DecryptAndDecode
196};
197
198template <> const char* interface_name<PPB_ContentDecryptor_Private>() {
199  return PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE;
200}
201
202}  // namespace
203
204ContentDecryptor_Private::ContentDecryptor_Private(Instance* instance)
205    : associated_instance_(instance) {
206  Module::Get()->AddPluginInterface(kPPPContentDecryptorInterface,
207                                    &ppp_content_decryptor);
208  instance->AddPerInstanceObject(kPPPContentDecryptorInterface, this);
209}
210
211ContentDecryptor_Private::~ContentDecryptor_Private() {
212  Instance::RemovePerInstanceObject(associated_instance_,
213                                    kPPPContentDecryptorInterface,
214                                    this);
215}
216
217void ContentDecryptor_Private::NeedKey(const std::string& key_system,
218                                       const std::string& session_id,
219                                       pp::VarArrayBuffer init_data) {
220  // session_id can be empty here.
221  if (has_interface<PPB_ContentDecryptor_Private>()) {
222    pp::Var key_system_var(key_system);
223    pp::Var session_id_var(session_id);
224
225    get_interface<PPB_ContentDecryptor_Private>()->NeedKey(
226        associated_instance_.pp_instance(),
227        key_system_var.pp_var(),
228        session_id_var.pp_var(),
229        init_data.pp_var());
230  }
231}
232
233void ContentDecryptor_Private::KeyAdded(const std::string& key_system,
234                                        const std::string& session_id) {
235  if (has_interface<PPB_ContentDecryptor_Private>()) {
236    pp::Var key_system_var(key_system);
237    pp::Var session_id_var(session_id);
238    get_interface<PPB_ContentDecryptor_Private>()->KeyAdded(
239        associated_instance_.pp_instance(),
240        key_system_var.pp_var(),
241        session_id_var.pp_var());
242  }
243}
244
245void ContentDecryptor_Private::KeyMessage(const std::string& key_system,
246                                          const std::string& session_id,
247                                          pp::VarArrayBuffer message,
248                                          const std::string& default_url) {
249  if (has_interface<PPB_ContentDecryptor_Private>()) {
250    pp::Var key_system_var(key_system);
251    pp::Var session_id_var(session_id);
252    pp::Var default_url_var(default_url);
253    get_interface<PPB_ContentDecryptor_Private>()->KeyMessage(
254        associated_instance_.pp_instance(),
255        key_system_var.pp_var(),
256        session_id_var.pp_var(),
257        message.pp_var(),
258        default_url_var.pp_var());
259  }
260}
261
262void ContentDecryptor_Private::KeyError(const std::string& key_system,
263                                        const std::string& session_id,
264                                        int32_t media_error,
265                                        int32_t system_code) {
266  if (has_interface<PPB_ContentDecryptor_Private>()) {
267    pp::Var key_system_var(key_system);
268    pp::Var session_id_var(session_id);
269    get_interface<PPB_ContentDecryptor_Private>()->KeyError(
270        associated_instance_.pp_instance(),
271        key_system_var.pp_var(),
272        session_id_var.pp_var(),
273        media_error,
274        system_code);
275  }
276}
277
278void ContentDecryptor_Private::DeliverBlock(
279    pp::Buffer_Dev decrypted_block,
280    const PP_DecryptedBlockInfo& decrypted_block_info) {
281  if (has_interface<PPB_ContentDecryptor_Private>()) {
282    get_interface<PPB_ContentDecryptor_Private>()->DeliverBlock(
283        associated_instance_.pp_instance(),
284        decrypted_block.pp_resource(),
285        &decrypted_block_info);
286  }
287}
288
289void ContentDecryptor_Private::DecoderInitializeDone(
290    PP_DecryptorStreamType decoder_type,
291    uint32_t request_id,
292    bool success) {
293  if (has_interface<PPB_ContentDecryptor_Private>()) {
294    get_interface<PPB_ContentDecryptor_Private>()->DecoderInitializeDone(
295        associated_instance_.pp_instance(),
296        decoder_type,
297        request_id,
298        PP_FromBool(success));
299  }
300}
301
302void ContentDecryptor_Private::DecoderDeinitializeDone(
303    PP_DecryptorStreamType decoder_type,
304    uint32_t request_id) {
305  if (has_interface<PPB_ContentDecryptor_Private>()) {
306    get_interface<PPB_ContentDecryptor_Private>()->DecoderDeinitializeDone(
307        associated_instance_.pp_instance(),
308        decoder_type,
309        request_id);
310  }
311}
312
313void ContentDecryptor_Private::DecoderResetDone(
314    PP_DecryptorStreamType decoder_type,
315    uint32_t request_id) {
316  if (has_interface<PPB_ContentDecryptor_Private>()) {
317    get_interface<PPB_ContentDecryptor_Private>()->DecoderResetDone(
318        associated_instance_.pp_instance(),
319        decoder_type,
320        request_id);
321  }
322}
323
324void ContentDecryptor_Private::DeliverFrame(
325    pp::Buffer_Dev decrypted_frame,
326    const PP_DecryptedFrameInfo& decrypted_frame_info) {
327  if (has_interface<PPB_ContentDecryptor_Private>()) {
328    get_interface<PPB_ContentDecryptor_Private>()->DeliverFrame(
329        associated_instance_.pp_instance(),
330        decrypted_frame.pp_resource(),
331        &decrypted_frame_info);
332  }
333}
334
335void ContentDecryptor_Private::DeliverSamples(
336    pp::Buffer_Dev audio_frames,
337    const PP_DecryptedBlockInfo& decrypted_block_info) {
338  if (has_interface<PPB_ContentDecryptor_Private>()) {
339    get_interface<PPB_ContentDecryptor_Private>()->DeliverSamples(
340        associated_instance_.pp_instance(),
341        audio_frames.pp_resource(),
342        &decrypted_block_info);
343  }
344}
345
346}  // namespace pp
347