blob: feafca7c4bc5b9e44743cc2eafae0570f1de9be7 [file] [log] [blame]
// 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<PepperPluginInstanceImpl> 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<PepperWebPluginImpl*>(web_plugin);
return ppapi_plugin->instance();
}
static scoped_ptr<media::MediaKeys> 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<PepperPluginInstanceImpl>& plugin_instance =
CreateHelperPlugin(plugin_type, web_media_player_client, web_frame);
if (!plugin_instance.get()) {
DLOG(ERROR) << "Plugin instance creation failed.";
return scoped_ptr<media::MediaKeys>();
}
scoped_ptr<PpapiDecryptor> 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<media::MediaKeys>(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<media::MediaKeys> 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<media::MediaKeys>(
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<media::MediaKeys>();
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<ProxyMediaKeys> 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<media::MediaKeys>();
#else
return scoped_ptr<media::MediaKeys>();
#endif // defined(ENABLE_PEPPER_CDMS)
}
} // namespace content