1 // Copyright 2013 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 "content/renderer/media/crypto/content_decryption_module_factory.h" 6 7 #include "base/logging.h" 8 #include "content/renderer/media/crypto/key_systems.h" 9 #include "media/cdm/aes_decryptor.h" 10 11 #if defined(ENABLE_PEPPER_CDMS) 12 #include "content/renderer/media/crypto/ppapi_decryptor.h" 13 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" 14 #include "content/renderer/pepper/pepper_webplugin_impl.h" 15 #include "third_party/WebKit/public/platform/WebMediaPlayerClient.h" 16 #include "third_party/WebKit/public/platform/WebString.h" 17 #include "third_party/WebKit/public/web/WebFrame.h" 18 #elif defined(OS_ANDROID) 19 #include "content/renderer/media/android/proxy_media_keys.h" 20 #include "content/renderer/media/android/renderer_media_player_manager.h" 21 #endif // defined(ENABLE_PEPPER_CDMS) 22 23 namespace content { 24 25 #if defined(ENABLE_PEPPER_CDMS) 26 // Returns the PepperPluginInstanceImpl associated with the Helper Plugin. 27 // If a non-NULL pointer is returned, the caller must call 28 // closeHelperPluginSoon() when the Helper Plugin is no longer needed. 29 static scoped_refptr<PepperPluginInstanceImpl> CreateHelperPlugin( 30 const std::string& plugin_type, 31 blink::WebMediaPlayerClient* web_media_player_client, 32 blink::WebFrame* web_frame) { 33 DCHECK(web_media_player_client); 34 DCHECK(web_frame); 35 36 blink::WebPlugin* web_plugin = web_media_player_client->createHelperPlugin( 37 blink::WebString::fromUTF8(plugin_type), web_frame); 38 if (!web_plugin) 39 return NULL; 40 41 DCHECK(!web_plugin->isPlaceholder()); // Prevented by Blink. 42 // Only Pepper plugins are supported, so it must be a ppapi object. 43 PepperWebPluginImpl* ppapi_plugin = 44 static_cast<PepperWebPluginImpl*>(web_plugin); 45 return ppapi_plugin->instance(); 46 } 47 48 static scoped_ptr<media::MediaKeys> CreatePpapiDecryptor( 49 const std::string& key_system, 50 const media::SessionCreatedCB& session_created_cb, 51 const media::SessionMessageCB& session_message_cb, 52 const media::SessionReadyCB& session_ready_cb, 53 const media::SessionClosedCB& session_closed_cb, 54 const media::SessionErrorCB& session_error_cb, 55 const base::Closure& destroy_plugin_cb, 56 blink::WebMediaPlayerClient* web_media_player_client, 57 blink::WebFrame* web_frame) { 58 DCHECK(web_media_player_client); 59 DCHECK(web_frame); 60 61 std::string plugin_type = GetPepperType(key_system); 62 DCHECK(!plugin_type.empty()); 63 const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance = 64 CreateHelperPlugin(plugin_type, web_media_player_client, web_frame); 65 if (!plugin_instance.get()) { 66 DLOG(ERROR) << "Plugin instance creation failed."; 67 return scoped_ptr<media::MediaKeys>(); 68 } 69 70 scoped_ptr<PpapiDecryptor> decryptor = 71 PpapiDecryptor::Create(key_system, 72 plugin_instance, 73 session_created_cb, 74 session_message_cb, 75 session_ready_cb, 76 session_closed_cb, 77 session_error_cb, 78 destroy_plugin_cb); 79 80 if (!decryptor) 81 destroy_plugin_cb.Run(); 82 // Else the new object will call destroy_plugin_cb to destroy Helper Plugin. 83 84 return scoped_ptr<media::MediaKeys>(decryptor.Pass()); 85 } 86 87 void ContentDecryptionModuleFactory::DestroyHelperPlugin( 88 blink::WebMediaPlayerClient* web_media_player_client, 89 blink::WebFrame* web_frame) { 90 web_media_player_client->closeHelperPluginSoon(web_frame); 91 } 92 #endif // defined(ENABLE_PEPPER_CDMS) 93 94 scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( 95 const std::string& key_system, 96 #if defined(ENABLE_PEPPER_CDMS) 97 blink::WebMediaPlayerClient* web_media_player_client, 98 blink::WebFrame* web_frame, 99 const base::Closure& destroy_plugin_cb, 100 #elif defined(OS_ANDROID) 101 RendererMediaPlayerManager* manager, 102 int media_keys_id, 103 const GURL& frame_url, 104 #endif // defined(ENABLE_PEPPER_CDMS) 105 const media::SessionCreatedCB& session_created_cb, 106 const media::SessionMessageCB& session_message_cb, 107 const media::SessionReadyCB& session_ready_cb, 108 const media::SessionClosedCB& session_closed_cb, 109 const media::SessionErrorCB& session_error_cb) { 110 if (CanUseAesDecryptor(key_system)) { 111 return scoped_ptr<media::MediaKeys>( 112 new media::AesDecryptor(session_created_cb, 113 session_message_cb, 114 session_ready_cb, 115 session_closed_cb, 116 session_error_cb)); 117 } 118 119 #if defined(ENABLE_PEPPER_CDMS) 120 // TODO(ddorwin): Remove when the WD API implementation supports loading 121 // Pepper-based CDMs: http://crbug.com/250049 122 if (!web_media_player_client) 123 return scoped_ptr<media::MediaKeys>(); 124 125 return CreatePpapiDecryptor(key_system, 126 session_created_cb, 127 session_message_cb, 128 session_ready_cb, 129 session_closed_cb, 130 session_error_cb, 131 destroy_plugin_cb, 132 web_media_player_client, 133 web_frame); 134 #elif defined(OS_ANDROID) 135 scoped_ptr<ProxyMediaKeys> proxy_media_keys( 136 new ProxyMediaKeys(manager, 137 media_keys_id, 138 session_created_cb, 139 session_message_cb, 140 session_ready_cb, 141 session_closed_cb, 142 session_error_cb)); 143 proxy_media_keys->InitializeCDM(key_system, frame_url); 144 return proxy_media_keys.PassAs<media::MediaKeys>(); 145 #else 146 return scoped_ptr<media::MediaKeys>(); 147 #endif // defined(ENABLE_PEPPER_CDMS) 148 } 149 150 } // namespace content 151