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