Home | History | Annotate | Download | only in crypto
      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