Revert 233414 "x11: Move XInput2 availability information out of..."
[chromium-blink-merge.git] / ppapi / proxy / ppp_content_decryptor_private_proxy.cc
blobd32e632009401bad808a0d261aeffe42e3493854
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/proxy/ppp_content_decryptor_private_proxy.h"
7 #include "base/platform_file.h"
8 #include "ppapi/c/pp_bool.h"
9 #include "ppapi/c/ppb_core.h"
10 #include "ppapi/proxy/content_decryptor_private_serializer.h"
11 #include "ppapi/proxy/host_dispatcher.h"
12 #include "ppapi/proxy/plugin_globals.h"
13 #include "ppapi/proxy/plugin_resource_tracker.h"
14 #include "ppapi/proxy/ppapi_messages.h"
15 #include "ppapi/proxy/ppb_buffer_proxy.h"
16 #include "ppapi/proxy/serialized_var.h"
17 #include "ppapi/shared_impl/scoped_pp_resource.h"
18 #include "ppapi/shared_impl/var_tracker.h"
19 #include "ppapi/thunk/enter.h"
20 #include "ppapi/thunk/ppb_buffer_api.h"
21 #include "ppapi/thunk/ppb_instance_api.h"
22 #include "ppapi/thunk/thunk.h"
24 using ppapi::thunk::EnterResourceNoLock;
25 using ppapi::thunk::PPB_Buffer_API;
26 using ppapi::thunk::PPB_Instance_API;
28 namespace ppapi {
29 namespace proxy {
31 namespace {
33 PP_Bool DescribeHostBufferResource(PP_Resource resource, uint32_t* size) {
34 EnterResourceNoLock<PPB_Buffer_API> enter(resource, true);
35 if (enter.failed())
36 return PP_FALSE;
37 return enter.object()->Describe(size);
40 // TODO(dmichael): Refactor so this handle sharing code is in one place.
41 PP_Bool ShareHostBufferResourceToPlugin(
42 HostDispatcher* dispatcher,
43 PP_Resource resource,
44 base::SharedMemoryHandle* shared_mem_handle) {
45 if (!dispatcher || resource == 0 || !shared_mem_handle)
46 return PP_FALSE;
47 EnterResourceNoLock<PPB_Buffer_API> enter(resource, true);
48 if (enter.failed())
49 return PP_FALSE;
50 int handle;
51 int32_t result = enter.object()->GetSharedMemory(&handle);
52 if (result != PP_OK)
53 return PP_FALSE;
54 base::PlatformFile platform_file =
55 #if defined(OS_WIN)
56 reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle));
57 #elif defined(OS_POSIX)
58 handle;
59 #else
60 #error Not implemented.
61 #endif
63 *shared_mem_handle = dispatcher->ShareHandleWithRemote(platform_file, false);
64 return PP_TRUE;
67 // SerializedVarReceiveInput will decrement the reference count, but we want
68 // to give the recipient a reference. This utility function takes care of that
69 // work for the message handlers defined below.
70 PP_Var ExtractReceivedVarAndAddRef(Dispatcher* dispatcher,
71 SerializedVarReceiveInput* serialized_var) {
72 PP_Var var = serialized_var->Get(dispatcher);
73 PpapiGlobals::Get()->GetVarTracker()->AddRefVar(var);
74 return var;
77 bool InitializePppDecryptorBuffer(PP_Instance instance,
78 HostDispatcher* dispatcher,
79 PP_Resource resource,
80 PPPDecryptor_Buffer* buffer) {
81 if (!buffer) {
82 NOTREACHED();
83 return false;
86 if (resource == 0) {
87 buffer->resource = HostResource();
88 buffer->handle = base::SharedMemoryHandle();
89 buffer->size = 0;
90 return true;
93 HostResource host_resource;
94 host_resource.SetHostResource(instance, resource);
96 uint32_t size = 0;
97 if (DescribeHostBufferResource(resource, &size) == PP_FALSE)
98 return false;
100 base::SharedMemoryHandle handle;
101 if (ShareHostBufferResourceToPlugin(dispatcher,
102 resource,
103 &handle) == PP_FALSE)
104 return false;
106 buffer->resource = host_resource;
107 buffer->handle = handle;
108 buffer->size = size;
109 return true;
112 void Initialize(PP_Instance instance,
113 PP_Var key_system,
114 PP_Bool can_challenge_platform) {
115 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
116 if (!dispatcher) {
117 NOTREACHED();
118 return;
121 dispatcher->Send(
122 new PpapiMsg_PPPContentDecryptor_Initialize(
123 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
124 instance,
125 SerializedVarSendInput(dispatcher, key_system),
126 PP_ToBool(can_challenge_platform)));
129 void GenerateKeyRequest(PP_Instance instance,
130 PP_Var type,
131 PP_Var init_data) {
132 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
133 if (!dispatcher) {
134 NOTREACHED();
135 return;
138 dispatcher->Send(
139 new PpapiMsg_PPPContentDecryptor_GenerateKeyRequest(
140 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
141 instance,
142 SerializedVarSendInput(dispatcher, type),
143 SerializedVarSendInput(dispatcher, init_data)));
146 void AddKey(PP_Instance instance,
147 PP_Var session_id,
148 PP_Var key,
149 PP_Var init_data) {
150 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
151 if (!dispatcher) {
152 NOTREACHED();
153 return;
156 dispatcher->Send(
157 new PpapiMsg_PPPContentDecryptor_AddKey(
158 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
159 instance,
160 SerializedVarSendInput(dispatcher, session_id),
161 SerializedVarSendInput(dispatcher, key),
162 SerializedVarSendInput(dispatcher, init_data)));
165 void CancelKeyRequest(PP_Instance instance, PP_Var session_id) {
166 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
167 if (!dispatcher) {
168 NOTREACHED();
169 return;
172 dispatcher->Send(
173 new PpapiMsg_PPPContentDecryptor_CancelKeyRequest(
174 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
175 instance,
176 SerializedVarSendInput(dispatcher, session_id)));
179 void Decrypt(PP_Instance instance,
180 PP_Resource encrypted_block,
181 const PP_EncryptedBlockInfo* encrypted_block_info) {
182 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
183 if (!dispatcher) {
184 NOTREACHED();
185 return;
188 PPPDecryptor_Buffer buffer;
189 if (!InitializePppDecryptorBuffer(instance,
190 dispatcher,
191 encrypted_block,
192 &buffer)) {
193 NOTREACHED();
194 return;
197 std::string serialized_block_info;
198 if (!SerializeBlockInfo(*encrypted_block_info, &serialized_block_info)) {
199 NOTREACHED();
200 return;
203 // PluginResourceTracker in the plugin process assumes that resources that it
204 // tracks have been addrefed on behalf of the plugin at the renderer side. So
205 // we explicitly do it for |encryped_block| here.
206 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(encrypted_block);
208 dispatcher->Send(
209 new PpapiMsg_PPPContentDecryptor_Decrypt(
210 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
211 instance,
212 buffer,
213 serialized_block_info));
216 void InitializeAudioDecoder(
217 PP_Instance instance,
218 const PP_AudioDecoderConfig* decoder_config,
219 PP_Resource extra_data_buffer) {
220 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
221 if (!dispatcher) {
222 NOTREACHED();
223 return;
226 std::string serialized_decoder_config;
227 if (!SerializeBlockInfo(*decoder_config, &serialized_decoder_config)) {
228 NOTREACHED();
229 return;
232 PPPDecryptor_Buffer buffer;
233 if (!InitializePppDecryptorBuffer(instance,
234 dispatcher,
235 extra_data_buffer,
236 &buffer)) {
237 NOTREACHED();
238 return;
241 // PluginResourceTracker in the plugin process assumes that resources that it
242 // tracks have been addrefed on behalf of the plugin at the renderer side. So
243 // we explicitly do it for |extra_data_buffer| here.
244 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(extra_data_buffer);
246 dispatcher->Send(
247 new PpapiMsg_PPPContentDecryptor_InitializeAudioDecoder(
248 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
249 instance,
250 serialized_decoder_config,
251 buffer));
254 void InitializeVideoDecoder(
255 PP_Instance instance,
256 const PP_VideoDecoderConfig* decoder_config,
257 PP_Resource extra_data_buffer) {
258 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
259 if (!dispatcher) {
260 NOTREACHED();
261 return;
264 std::string serialized_decoder_config;
265 if (!SerializeBlockInfo(*decoder_config, &serialized_decoder_config)) {
266 NOTREACHED();
267 return;
270 PPPDecryptor_Buffer buffer;
271 if (!InitializePppDecryptorBuffer(instance,
272 dispatcher,
273 extra_data_buffer,
274 &buffer)) {
275 NOTREACHED();
276 return;
279 // PluginResourceTracker in the plugin process assumes that resources that it
280 // tracks have been addrefed on behalf of the plugin at the renderer side. So
281 // we explicitly do it for |extra_data_buffer| here.
282 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(extra_data_buffer);
284 dispatcher->Send(
285 new PpapiMsg_PPPContentDecryptor_InitializeVideoDecoder(
286 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
287 instance,
288 serialized_decoder_config,
289 buffer));
293 void DeinitializeDecoder(PP_Instance instance,
294 PP_DecryptorStreamType decoder_type,
295 uint32_t request_id) {
296 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
297 if (!dispatcher) {
298 NOTREACHED();
299 return;
302 dispatcher->Send(
303 new PpapiMsg_PPPContentDecryptor_DeinitializeDecoder(
304 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
305 instance,
306 decoder_type,
307 request_id));
310 void ResetDecoder(PP_Instance instance,
311 PP_DecryptorStreamType decoder_type,
312 uint32_t request_id) {
313 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
314 if (!dispatcher) {
315 NOTREACHED();
316 return;
319 dispatcher->Send(
320 new PpapiMsg_PPPContentDecryptor_ResetDecoder(
321 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
322 instance,
323 decoder_type,
324 request_id));
327 void DecryptAndDecode(PP_Instance instance,
328 PP_DecryptorStreamType decoder_type,
329 PP_Resource encrypted_buffer,
330 const PP_EncryptedBlockInfo* encrypted_block_info) {
331 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
332 if (!dispatcher) {
333 NOTREACHED();
334 return;
337 PPPDecryptor_Buffer buffer;
338 if (!InitializePppDecryptorBuffer(instance,
339 dispatcher,
340 encrypted_buffer,
341 &buffer)) {
342 NOTREACHED();
343 return;
346 std::string serialized_block_info;
347 if (!SerializeBlockInfo(*encrypted_block_info, &serialized_block_info)) {
348 NOTREACHED();
349 return;
352 // PluginResourceTracker in the plugin process assumes that resources that it
353 // tracks have been addrefed on behalf of the plugin at the renderer side. So
354 // we explicitly do it for |encrypted_buffer| here.
355 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(encrypted_buffer);
357 dispatcher->Send(
358 new PpapiMsg_PPPContentDecryptor_DecryptAndDecode(
359 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
360 instance,
361 decoder_type,
362 buffer,
363 serialized_block_info));
366 static const PPP_ContentDecryptor_Private content_decryptor_interface = {
367 &Initialize,
368 &GenerateKeyRequest,
369 &AddKey,
370 &CancelKeyRequest,
371 &Decrypt,
372 &InitializeAudioDecoder,
373 &InitializeVideoDecoder,
374 &DeinitializeDecoder,
375 &ResetDecoder,
376 &DecryptAndDecode
379 } // namespace
381 PPP_ContentDecryptor_Private_Proxy::PPP_ContentDecryptor_Private_Proxy(
382 Dispatcher* dispatcher)
383 : InterfaceProxy(dispatcher),
384 ppp_decryptor_impl_(NULL) {
385 if (dispatcher->IsPlugin()) {
386 ppp_decryptor_impl_ = static_cast<const PPP_ContentDecryptor_Private*>(
387 dispatcher->local_get_interface()(
388 PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE));
392 PPP_ContentDecryptor_Private_Proxy::~PPP_ContentDecryptor_Private_Proxy() {
395 // static
396 const PPP_ContentDecryptor_Private*
397 PPP_ContentDecryptor_Private_Proxy::GetProxyInterface() {
398 return &content_decryptor_interface;
401 bool PPP_ContentDecryptor_Private_Proxy::OnMessageReceived(
402 const IPC::Message& msg) {
403 if (!dispatcher()->IsPlugin())
404 return false; // These are only valid from host->plugin.
405 // Don't allow the plugin to send these to the host.
407 bool handled = true;
408 IPC_BEGIN_MESSAGE_MAP(PPP_ContentDecryptor_Private_Proxy, msg)
409 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_Initialize,
410 OnMsgInitialize)
411 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_GenerateKeyRequest,
412 OnMsgGenerateKeyRequest)
413 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_AddKey,
414 OnMsgAddKey)
415 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_CancelKeyRequest,
416 OnMsgCancelKeyRequest)
417 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_Decrypt,
418 OnMsgDecrypt)
419 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_InitializeAudioDecoder,
420 OnMsgInitializeAudioDecoder)
421 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_InitializeVideoDecoder,
422 OnMsgInitializeVideoDecoder)
423 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_DeinitializeDecoder,
424 OnMsgDeinitializeDecoder)
425 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_ResetDecoder,
426 OnMsgResetDecoder)
427 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_DecryptAndDecode,
428 OnMsgDecryptAndDecode)
429 IPC_MESSAGE_UNHANDLED(handled = false)
430 IPC_END_MESSAGE_MAP()
431 DCHECK(handled);
432 return handled;
435 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitialize(
436 PP_Instance instance,
437 SerializedVarReceiveInput key_system,
438 bool can_challenge_platform) {
439 if (ppp_decryptor_impl_) {
440 CallWhileUnlocked(
441 ppp_decryptor_impl_->Initialize,
442 instance,
443 ExtractReceivedVarAndAddRef(dispatcher(), &key_system),
444 PP_FromBool(can_challenge_platform));
448 void PPP_ContentDecryptor_Private_Proxy::OnMsgGenerateKeyRequest(
449 PP_Instance instance,
450 SerializedVarReceiveInput type,
451 SerializedVarReceiveInput init_data) {
452 if (ppp_decryptor_impl_) {
453 CallWhileUnlocked(ppp_decryptor_impl_->GenerateKeyRequest,
454 instance,
455 ExtractReceivedVarAndAddRef(dispatcher(), &type),
456 ExtractReceivedVarAndAddRef(dispatcher(), &init_data));
460 void PPP_ContentDecryptor_Private_Proxy::OnMsgAddKey(
461 PP_Instance instance,
462 SerializedVarReceiveInput session_id,
463 SerializedVarReceiveInput key,
464 SerializedVarReceiveInput init_data) {
465 if (ppp_decryptor_impl_) {
466 CallWhileUnlocked(ppp_decryptor_impl_->AddKey,
467 instance,
468 ExtractReceivedVarAndAddRef(dispatcher(), &session_id),
469 ExtractReceivedVarAndAddRef(dispatcher(), &key),
470 ExtractReceivedVarAndAddRef(dispatcher(), &init_data));
474 void PPP_ContentDecryptor_Private_Proxy::OnMsgCancelKeyRequest(
475 PP_Instance instance,
476 SerializedVarReceiveInput session_id) {
477 if (ppp_decryptor_impl_) {
478 CallWhileUnlocked(ppp_decryptor_impl_->CancelKeyRequest,
479 instance,
480 ExtractReceivedVarAndAddRef(dispatcher(), &session_id));
484 void PPP_ContentDecryptor_Private_Proxy::OnMsgDecrypt(
485 PP_Instance instance,
486 const PPPDecryptor_Buffer& encrypted_buffer,
487 const std::string& serialized_block_info) {
488 ScopedPPResource plugin_resource(
489 ScopedPPResource::PassRef(),
490 PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource,
491 encrypted_buffer.handle,
492 encrypted_buffer.size));
493 if (ppp_decryptor_impl_) {
494 PP_EncryptedBlockInfo block_info;
495 if (!DeserializeBlockInfo(serialized_block_info, &block_info))
496 return;
497 CallWhileUnlocked(ppp_decryptor_impl_->Decrypt,
498 instance,
499 plugin_resource.get(),
500 const_cast<const PP_EncryptedBlockInfo*>(&block_info));
504 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitializeAudioDecoder(
505 PP_Instance instance,
506 const std::string& serialized_decoder_config,
507 const PPPDecryptor_Buffer& extra_data_buffer) {
508 ScopedPPResource plugin_resource;
509 if (extra_data_buffer.size > 0) {
510 plugin_resource = ScopedPPResource(
511 ScopedPPResource::PassRef(),
512 PPB_Buffer_Proxy::AddProxyResource(extra_data_buffer.resource,
513 extra_data_buffer.handle,
514 extra_data_buffer.size));
517 PP_AudioDecoderConfig decoder_config;
518 if (!DeserializeBlockInfo(serialized_decoder_config, &decoder_config))
519 return;
521 if (ppp_decryptor_impl_) {
522 CallWhileUnlocked(
523 ppp_decryptor_impl_->InitializeAudioDecoder,
524 instance,
525 const_cast<const PP_AudioDecoderConfig*>(&decoder_config),
526 plugin_resource.get());
530 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitializeVideoDecoder(
531 PP_Instance instance,
532 const std::string& serialized_decoder_config,
533 const PPPDecryptor_Buffer& extra_data_buffer) {
534 ScopedPPResource plugin_resource;
535 if (extra_data_buffer.resource.host_resource() != 0) {
536 plugin_resource = ScopedPPResource(
537 ScopedPPResource::PassRef(),
538 PPB_Buffer_Proxy::AddProxyResource(extra_data_buffer.resource,
539 extra_data_buffer.handle,
540 extra_data_buffer.size));
543 PP_VideoDecoderConfig decoder_config;
544 if (!DeserializeBlockInfo(serialized_decoder_config, &decoder_config))
545 return;
547 if (ppp_decryptor_impl_) {
548 CallWhileUnlocked(
549 ppp_decryptor_impl_->InitializeVideoDecoder,
550 instance,
551 const_cast<const PP_VideoDecoderConfig*>(&decoder_config),
552 plugin_resource.get());
556 void PPP_ContentDecryptor_Private_Proxy::OnMsgDeinitializeDecoder(
557 PP_Instance instance,
558 PP_DecryptorStreamType decoder_type,
559 uint32_t request_id) {
560 if (ppp_decryptor_impl_) {
561 CallWhileUnlocked(
562 ppp_decryptor_impl_->DeinitializeDecoder,
563 instance,
564 decoder_type,
565 request_id);
569 void PPP_ContentDecryptor_Private_Proxy::OnMsgResetDecoder(
570 PP_Instance instance,
571 PP_DecryptorStreamType decoder_type,
572 uint32_t request_id) {
573 if (ppp_decryptor_impl_) {
574 CallWhileUnlocked(
575 ppp_decryptor_impl_->ResetDecoder,
576 instance,
577 decoder_type,
578 request_id);
582 void PPP_ContentDecryptor_Private_Proxy::OnMsgDecryptAndDecode(
583 PP_Instance instance,
584 PP_DecryptorStreamType decoder_type,
585 const PPPDecryptor_Buffer& encrypted_buffer,
586 const std::string& serialized_block_info) {
587 ScopedPPResource plugin_resource;
588 if (encrypted_buffer.resource.host_resource() != 0) {
589 plugin_resource = ScopedPPResource(
590 ScopedPPResource::PassRef(),
591 PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource,
592 encrypted_buffer.handle,
593 encrypted_buffer.size));
596 if (ppp_decryptor_impl_) {
597 PP_EncryptedBlockInfo block_info;
598 if (!DeserializeBlockInfo(serialized_block_info, &block_info))
599 return;
600 CallWhileUnlocked(
601 ppp_decryptor_impl_->DecryptAndDecode,
602 instance,
603 decoder_type,
604 plugin_resource.get(),
605 const_cast<const PP_EncryptedBlockInfo*>(&block_info));
609 } // namespace proxy
610 } // namespace ppapi