Revert 251029 "Move Windows-specific code into NativeAppWindowVi..."
[chromium-blink-merge.git] / ppapi / proxy / ppp_content_decryptor_private_proxy.cc
blobda0209764baedbafb28057375f0fdee29b0da0e1
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 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
115 if (!dispatcher) {
116 NOTREACHED();
117 return;
120 dispatcher->Send(
121 new PpapiMsg_PPPContentDecryptor_Initialize(
122 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
123 instance,
124 SerializedVarSendInput(dispatcher, key_system)));
127 void CreateSession(PP_Instance instance,
128 uint32_t session_id,
129 PP_Var type,
130 PP_Var init_data) {
131 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
132 if (!dispatcher) {
133 NOTREACHED();
134 return;
137 dispatcher->Send(new PpapiMsg_PPPContentDecryptor_CreateSession(
138 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
139 instance,
140 session_id,
141 SerializedVarSendInput(dispatcher, type),
142 SerializedVarSendInput(dispatcher, init_data)));
145 void LoadSession(PP_Instance instance,
146 uint32_t session_id,
147 PP_Var web_session_id) {
148 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
149 if (!dispatcher) {
150 NOTREACHED();
151 return;
154 dispatcher->Send(new PpapiMsg_PPPContentDecryptor_LoadSession(
155 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
156 instance,
157 session_id,
158 SerializedVarSendInput(dispatcher, web_session_id)));
161 void UpdateSession(PP_Instance instance, uint32_t session_id, PP_Var response) {
162 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
163 if (!dispatcher) {
164 NOTREACHED();
165 return;
168 dispatcher->Send(new PpapiMsg_PPPContentDecryptor_UpdateSession(
169 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
170 instance,
171 session_id,
172 SerializedVarSendInput(dispatcher, response)));
175 void ReleaseSession(PP_Instance instance, uint32_t session_id) {
176 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
177 if (!dispatcher) {
178 NOTREACHED();
179 return;
182 dispatcher->Send(new PpapiMsg_PPPContentDecryptor_ReleaseSession(
183 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, instance, session_id));
186 void Decrypt(PP_Instance instance,
187 PP_Resource encrypted_block,
188 const PP_EncryptedBlockInfo* encrypted_block_info) {
189 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
190 if (!dispatcher) {
191 NOTREACHED();
192 return;
195 PPPDecryptor_Buffer buffer;
196 if (!InitializePppDecryptorBuffer(instance,
197 dispatcher,
198 encrypted_block,
199 &buffer)) {
200 NOTREACHED();
201 return;
204 std::string serialized_block_info;
205 if (!SerializeBlockInfo(*encrypted_block_info, &serialized_block_info)) {
206 NOTREACHED();
207 return;
210 // PluginResourceTracker in the plugin process assumes that resources that it
211 // tracks have been addrefed on behalf of the plugin at the renderer side. So
212 // we explicitly do it for |encryped_block| here.
213 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(encrypted_block);
215 dispatcher->Send(
216 new PpapiMsg_PPPContentDecryptor_Decrypt(
217 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
218 instance,
219 buffer,
220 serialized_block_info));
223 void InitializeAudioDecoder(
224 PP_Instance instance,
225 const PP_AudioDecoderConfig* decoder_config,
226 PP_Resource extra_data_buffer) {
227 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
228 if (!dispatcher) {
229 NOTREACHED();
230 return;
233 std::string serialized_decoder_config;
234 if (!SerializeBlockInfo(*decoder_config, &serialized_decoder_config)) {
235 NOTREACHED();
236 return;
239 PPPDecryptor_Buffer buffer;
240 if (!InitializePppDecryptorBuffer(instance,
241 dispatcher,
242 extra_data_buffer,
243 &buffer)) {
244 NOTREACHED();
245 return;
248 // PluginResourceTracker in the plugin process assumes that resources that it
249 // tracks have been addrefed on behalf of the plugin at the renderer side. So
250 // we explicitly do it for |extra_data_buffer| here.
251 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(extra_data_buffer);
253 dispatcher->Send(
254 new PpapiMsg_PPPContentDecryptor_InitializeAudioDecoder(
255 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
256 instance,
257 serialized_decoder_config,
258 buffer));
261 void InitializeVideoDecoder(
262 PP_Instance instance,
263 const PP_VideoDecoderConfig* decoder_config,
264 PP_Resource extra_data_buffer) {
265 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
266 if (!dispatcher) {
267 NOTREACHED();
268 return;
271 std::string serialized_decoder_config;
272 if (!SerializeBlockInfo(*decoder_config, &serialized_decoder_config)) {
273 NOTREACHED();
274 return;
277 PPPDecryptor_Buffer buffer;
278 if (!InitializePppDecryptorBuffer(instance,
279 dispatcher,
280 extra_data_buffer,
281 &buffer)) {
282 NOTREACHED();
283 return;
286 // PluginResourceTracker in the plugin process assumes that resources that it
287 // tracks have been addrefed on behalf of the plugin at the renderer side. So
288 // we explicitly do it for |extra_data_buffer| here.
289 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(extra_data_buffer);
291 dispatcher->Send(
292 new PpapiMsg_PPPContentDecryptor_InitializeVideoDecoder(
293 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
294 instance,
295 serialized_decoder_config,
296 buffer));
300 void DeinitializeDecoder(PP_Instance instance,
301 PP_DecryptorStreamType decoder_type,
302 uint32_t request_id) {
303 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
304 if (!dispatcher) {
305 NOTREACHED();
306 return;
309 dispatcher->Send(
310 new PpapiMsg_PPPContentDecryptor_DeinitializeDecoder(
311 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
312 instance,
313 decoder_type,
314 request_id));
317 void ResetDecoder(PP_Instance instance,
318 PP_DecryptorStreamType decoder_type,
319 uint32_t request_id) {
320 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
321 if (!dispatcher) {
322 NOTREACHED();
323 return;
326 dispatcher->Send(
327 new PpapiMsg_PPPContentDecryptor_ResetDecoder(
328 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
329 instance,
330 decoder_type,
331 request_id));
334 void DecryptAndDecode(PP_Instance instance,
335 PP_DecryptorStreamType decoder_type,
336 PP_Resource encrypted_buffer,
337 const PP_EncryptedBlockInfo* encrypted_block_info) {
338 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance);
339 if (!dispatcher) {
340 NOTREACHED();
341 return;
344 PPPDecryptor_Buffer buffer;
345 if (!InitializePppDecryptorBuffer(instance,
346 dispatcher,
347 encrypted_buffer,
348 &buffer)) {
349 NOTREACHED();
350 return;
353 std::string serialized_block_info;
354 if (!SerializeBlockInfo(*encrypted_block_info, &serialized_block_info)) {
355 NOTREACHED();
356 return;
359 // PluginResourceTracker in the plugin process assumes that resources that it
360 // tracks have been addrefed on behalf of the plugin at the renderer side. So
361 // we explicitly do it for |encrypted_buffer| here.
362 PpapiGlobals::Get()->GetResourceTracker()->AddRefResource(encrypted_buffer);
364 dispatcher->Send(
365 new PpapiMsg_PPPContentDecryptor_DecryptAndDecode(
366 API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE,
367 instance,
368 decoder_type,
369 buffer,
370 serialized_block_info));
373 static const PPP_ContentDecryptor_Private content_decryptor_interface = {
374 &Initialize,
375 &CreateSession,
376 &LoadSession,
377 &UpdateSession,
378 &ReleaseSession,
379 &Decrypt,
380 &InitializeAudioDecoder,
381 &InitializeVideoDecoder,
382 &DeinitializeDecoder,
383 &ResetDecoder,
384 &DecryptAndDecode
387 } // namespace
389 PPP_ContentDecryptor_Private_Proxy::PPP_ContentDecryptor_Private_Proxy(
390 Dispatcher* dispatcher)
391 : InterfaceProxy(dispatcher),
392 ppp_decryptor_impl_(NULL) {
393 if (dispatcher->IsPlugin()) {
394 ppp_decryptor_impl_ = static_cast<const PPP_ContentDecryptor_Private*>(
395 dispatcher->local_get_interface()(
396 PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE));
400 PPP_ContentDecryptor_Private_Proxy::~PPP_ContentDecryptor_Private_Proxy() {
403 // static
404 const PPP_ContentDecryptor_Private*
405 PPP_ContentDecryptor_Private_Proxy::GetProxyInterface() {
406 return &content_decryptor_interface;
409 bool PPP_ContentDecryptor_Private_Proxy::OnMessageReceived(
410 const IPC::Message& msg) {
411 if (!dispatcher()->IsPlugin())
412 return false; // These are only valid from host->plugin.
413 // Don't allow the plugin to send these to the host.
415 bool handled = true;
416 IPC_BEGIN_MESSAGE_MAP(PPP_ContentDecryptor_Private_Proxy, msg)
417 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_Initialize,
418 OnMsgInitialize)
419 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_CreateSession,
420 OnMsgCreateSession)
421 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_LoadSession,
422 OnMsgLoadSession)
423 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_UpdateSession,
424 OnMsgUpdateSession)
425 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_ReleaseSession,
426 OnMsgReleaseSession)
427 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_Decrypt,
428 OnMsgDecrypt)
429 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_InitializeAudioDecoder,
430 OnMsgInitializeAudioDecoder)
431 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_InitializeVideoDecoder,
432 OnMsgInitializeVideoDecoder)
433 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_DeinitializeDecoder,
434 OnMsgDeinitializeDecoder)
435 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_ResetDecoder,
436 OnMsgResetDecoder)
437 IPC_MESSAGE_HANDLER(PpapiMsg_PPPContentDecryptor_DecryptAndDecode,
438 OnMsgDecryptAndDecode)
439 IPC_MESSAGE_UNHANDLED(handled = false)
440 IPC_END_MESSAGE_MAP()
441 DCHECK(handled);
442 return handled;
445 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitialize(
446 PP_Instance instance,
447 SerializedVarReceiveInput key_system) {
448 if (ppp_decryptor_impl_) {
449 CallWhileUnlocked(
450 ppp_decryptor_impl_->Initialize,
451 instance,
452 ExtractReceivedVarAndAddRef(dispatcher(), &key_system));
456 void PPP_ContentDecryptor_Private_Proxy::OnMsgCreateSession(
457 PP_Instance instance,
458 uint32_t session_id,
459 SerializedVarReceiveInput type,
460 SerializedVarReceiveInput init_data) {
461 if (ppp_decryptor_impl_) {
462 CallWhileUnlocked(ppp_decryptor_impl_->CreateSession,
463 instance,
464 session_id,
465 ExtractReceivedVarAndAddRef(dispatcher(), &type),
466 ExtractReceivedVarAndAddRef(dispatcher(), &init_data));
470 void PPP_ContentDecryptor_Private_Proxy::OnMsgLoadSession(
471 PP_Instance instance,
472 uint32_t session_id,
473 SerializedVarReceiveInput web_session_id) {
474 if (ppp_decryptor_impl_) {
475 CallWhileUnlocked(
476 ppp_decryptor_impl_->LoadSession,
477 instance,
478 session_id,
479 ExtractReceivedVarAndAddRef(dispatcher(), &web_session_id));
483 void PPP_ContentDecryptor_Private_Proxy::OnMsgUpdateSession(
484 PP_Instance instance,
485 uint32_t session_id,
486 SerializedVarReceiveInput response) {
487 if (ppp_decryptor_impl_) {
488 CallWhileUnlocked(ppp_decryptor_impl_->UpdateSession,
489 instance,
490 session_id,
491 ExtractReceivedVarAndAddRef(dispatcher(), &response));
495 void PPP_ContentDecryptor_Private_Proxy::OnMsgReleaseSession(
496 PP_Instance instance,
497 uint32_t session_id) {
498 if (ppp_decryptor_impl_) {
499 CallWhileUnlocked(ppp_decryptor_impl_->ReleaseSession,
500 instance,
501 session_id);
505 void PPP_ContentDecryptor_Private_Proxy::OnMsgDecrypt(
506 PP_Instance instance,
507 const PPPDecryptor_Buffer& encrypted_buffer,
508 const std::string& serialized_block_info) {
509 ScopedPPResource plugin_resource(
510 ScopedPPResource::PassRef(),
511 PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource,
512 encrypted_buffer.handle,
513 encrypted_buffer.size));
514 if (ppp_decryptor_impl_) {
515 PP_EncryptedBlockInfo block_info;
516 if (!DeserializeBlockInfo(serialized_block_info, &block_info))
517 return;
518 CallWhileUnlocked(ppp_decryptor_impl_->Decrypt,
519 instance,
520 plugin_resource.get(),
521 const_cast<const PP_EncryptedBlockInfo*>(&block_info));
525 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitializeAudioDecoder(
526 PP_Instance instance,
527 const std::string& serialized_decoder_config,
528 const PPPDecryptor_Buffer& extra_data_buffer) {
529 ScopedPPResource plugin_resource;
530 if (extra_data_buffer.size > 0) {
531 plugin_resource = ScopedPPResource(
532 ScopedPPResource::PassRef(),
533 PPB_Buffer_Proxy::AddProxyResource(extra_data_buffer.resource,
534 extra_data_buffer.handle,
535 extra_data_buffer.size));
538 PP_AudioDecoderConfig decoder_config;
539 if (!DeserializeBlockInfo(serialized_decoder_config, &decoder_config))
540 return;
542 if (ppp_decryptor_impl_) {
543 CallWhileUnlocked(
544 ppp_decryptor_impl_->InitializeAudioDecoder,
545 instance,
546 const_cast<const PP_AudioDecoderConfig*>(&decoder_config),
547 plugin_resource.get());
551 void PPP_ContentDecryptor_Private_Proxy::OnMsgInitializeVideoDecoder(
552 PP_Instance instance,
553 const std::string& serialized_decoder_config,
554 const PPPDecryptor_Buffer& extra_data_buffer) {
555 ScopedPPResource plugin_resource;
556 if (extra_data_buffer.resource.host_resource() != 0) {
557 plugin_resource = ScopedPPResource(
558 ScopedPPResource::PassRef(),
559 PPB_Buffer_Proxy::AddProxyResource(extra_data_buffer.resource,
560 extra_data_buffer.handle,
561 extra_data_buffer.size));
564 PP_VideoDecoderConfig decoder_config;
565 if (!DeserializeBlockInfo(serialized_decoder_config, &decoder_config))
566 return;
568 if (ppp_decryptor_impl_) {
569 CallWhileUnlocked(
570 ppp_decryptor_impl_->InitializeVideoDecoder,
571 instance,
572 const_cast<const PP_VideoDecoderConfig*>(&decoder_config),
573 plugin_resource.get());
577 void PPP_ContentDecryptor_Private_Proxy::OnMsgDeinitializeDecoder(
578 PP_Instance instance,
579 PP_DecryptorStreamType decoder_type,
580 uint32_t request_id) {
581 if (ppp_decryptor_impl_) {
582 CallWhileUnlocked(
583 ppp_decryptor_impl_->DeinitializeDecoder,
584 instance,
585 decoder_type,
586 request_id);
590 void PPP_ContentDecryptor_Private_Proxy::OnMsgResetDecoder(
591 PP_Instance instance,
592 PP_DecryptorStreamType decoder_type,
593 uint32_t request_id) {
594 if (ppp_decryptor_impl_) {
595 CallWhileUnlocked(
596 ppp_decryptor_impl_->ResetDecoder,
597 instance,
598 decoder_type,
599 request_id);
603 void PPP_ContentDecryptor_Private_Proxy::OnMsgDecryptAndDecode(
604 PP_Instance instance,
605 PP_DecryptorStreamType decoder_type,
606 const PPPDecryptor_Buffer& encrypted_buffer,
607 const std::string& serialized_block_info) {
608 ScopedPPResource plugin_resource;
609 if (encrypted_buffer.resource.host_resource() != 0) {
610 plugin_resource = ScopedPPResource(
611 ScopedPPResource::PassRef(),
612 PPB_Buffer_Proxy::AddProxyResource(encrypted_buffer.resource,
613 encrypted_buffer.handle,
614 encrypted_buffer.size));
617 if (ppp_decryptor_impl_) {
618 PP_EncryptedBlockInfo block_info;
619 if (!DeserializeBlockInfo(serialized_block_info, &block_info))
620 return;
621 CallWhileUnlocked(
622 ppp_decryptor_impl_->DecryptAndDecode,
623 instance,
624 decoder_type,
625 plugin_resource.get(),
626 const_cast<const PP_EncryptedBlockInfo*>(&block_info));
630 } // namespace proxy
631 } // namespace ppapi