// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/renderer/media/crypto/content_decryption_module_factory.h" #include "base/logging.h" #include "content/renderer/media/crypto/key_systems.h" #include "media/cdm/aes_decryptor.h" #if defined(ENABLE_PEPPER_CDMS) #include "content/renderer/media/crypto/ppapi_decryptor.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/pepper_webplugin_impl.h" #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/web/WebFrame.h" #elif defined(OS_ANDROID) #include "content/renderer/media/android/proxy_media_keys.h" #include "content/renderer/media/android/renderer_media_player_manager.h" #endif // defined(ENABLE_PEPPER_CDMS) namespace content { #if defined(ENABLE_PEPPER_CDMS) // Returns the PepperPluginInstanceImpl associated with the Helper Plugin. // If a non-NULL pointer is returned, the caller must call // closeHelperPluginSoon() when the Helper Plugin is no longer needed. static scoped_refptr CreateHelperPlugin( const std::string& plugin_type, blink::WebMediaPlayerClient* web_media_player_client, blink::WebFrame* web_frame) { DCHECK(web_media_player_client); DCHECK(web_frame); blink::WebPlugin* web_plugin = web_media_player_client->createHelperPlugin( blink::WebString::fromUTF8(plugin_type), web_frame); if (!web_plugin) return NULL; DCHECK(!web_plugin->isPlaceholder()); // Prevented by Blink. // Only Pepper plugins are supported, so it must be a ppapi object. PepperWebPluginImpl* ppapi_plugin = static_cast(web_plugin); return ppapi_plugin->instance(); } static scoped_ptr CreatePpapiDecryptor( const std::string& key_system, const media::SessionCreatedCB& session_created_cb, const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, const media::SessionErrorCB& session_error_cb, const base::Closure& destroy_plugin_cb, blink::WebMediaPlayerClient* web_media_player_client, blink::WebFrame* web_frame) { DCHECK(web_media_player_client); DCHECK(web_frame); std::string plugin_type = GetPepperType(key_system); DCHECK(!plugin_type.empty()); const scoped_refptr& plugin_instance = CreateHelperPlugin(plugin_type, web_media_player_client, web_frame); if (!plugin_instance.get()) { DLOG(ERROR) << "Plugin instance creation failed."; return scoped_ptr(); } scoped_ptr decryptor = PpapiDecryptor::Create(key_system, plugin_instance, session_created_cb, session_message_cb, session_ready_cb, session_closed_cb, session_error_cb, destroy_plugin_cb); if (!decryptor) destroy_plugin_cb.Run(); // Else the new object will call destroy_plugin_cb to destroy Helper Plugin. return scoped_ptr(decryptor.Pass()); } void ContentDecryptionModuleFactory::DestroyHelperPlugin( blink::WebMediaPlayerClient* web_media_player_client, blink::WebFrame* web_frame) { web_media_player_client->closeHelperPluginSoon(web_frame); } #endif // defined(ENABLE_PEPPER_CDMS) scoped_ptr ContentDecryptionModuleFactory::Create( const std::string& key_system, #if defined(ENABLE_PEPPER_CDMS) blink::WebMediaPlayerClient* web_media_player_client, blink::WebFrame* web_frame, const base::Closure& destroy_plugin_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, int media_keys_id, const GURL& frame_url, #endif // defined(ENABLE_PEPPER_CDMS) const media::SessionCreatedCB& session_created_cb, const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, const media::SessionErrorCB& session_error_cb) { if (CanUseAesDecryptor(key_system)) { return scoped_ptr( new media::AesDecryptor(session_created_cb, session_message_cb, session_ready_cb, session_closed_cb, session_error_cb)); } #if defined(ENABLE_PEPPER_CDMS) // TODO(ddorwin): Remove when the WD API implementation supports loading // Pepper-based CDMs: http://crbug.com/250049 if (!web_media_player_client) return scoped_ptr(); return CreatePpapiDecryptor(key_system, session_created_cb, session_message_cb, session_ready_cb, session_closed_cb, session_error_cb, destroy_plugin_cb, web_media_player_client, web_frame); #elif defined(OS_ANDROID) scoped_ptr proxy_media_keys( new ProxyMediaKeys(manager, media_keys_id, session_created_cb, session_message_cb, session_ready_cb, session_closed_cb, session_error_cb)); proxy_media_keys->InitializeCDM(key_system, frame_url); return proxy_media_keys.PassAs(); #else return scoped_ptr(); #endif // defined(ENABLE_PEPPER_CDMS) } } // namespace content