summaryrefslogtreecommitdiffstats
path: root/content/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'content/renderer')
-rw-r--r--content/renderer/BUILD.gn1
-rw-r--r--content/renderer/media/android/webmediaplayer_android.cc2
-rw-r--r--content/renderer/media/android/webmediaplayer_android.h4
-rw-r--r--content/renderer/media/crypto/encrypted_media_player_support_impl.cc475
-rw-r--r--content/renderer/media/crypto/encrypted_media_player_support_impl.h131
-rw-r--r--content/renderer/media/crypto/proxy_decryptor.cc312
-rw-r--r--content/renderer/media/crypto/proxy_decryptor.h131
-rw-r--r--content/renderer/render_frame_impl.cc13
8 files changed, 13 insertions, 1056 deletions
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 22acf49b..bfe9605 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -83,7 +83,6 @@ source_set("renderer") {
if (is_android) {
sources -= [
"media/audio_decoder.cc",
- "media/crypto/encrypted_media_player_support_impl.cc",
]
sources += [
"external_popup_menu.cc",
diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc
index 196b9a7..deb3417 100644
--- a/content/renderer/media/android/webmediaplayer_android.cc
+++ b/content/renderer/media/android/webmediaplayer_android.cc
@@ -1508,7 +1508,7 @@ WebMediaPlayerAndroid::GenerateKeyRequestInternal(
// We do not support run-time switching between key systems for now.
if (current_key_system_.empty()) {
if (!proxy_decryptor_) {
- proxy_decryptor_.reset(new ProxyDecryptor(
+ proxy_decryptor_.reset(new media::ProxyDecryptor(
base::Bind(&WebMediaPlayerAndroid::OnKeyAdded,
weak_factory_.GetWeakPtr()),
base::Bind(&WebMediaPlayerAndroid::OnKeyError,
diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h
index 771074d..0da37eb 100644
--- a/content/renderer/media/android/webmediaplayer_android.h
+++ b/content/renderer/media/android/webmediaplayer_android.h
@@ -22,12 +22,12 @@
#include "content/renderer/media/android/media_info_loader.h"
#include "content/renderer/media/android/media_source_delegate.h"
#include "content/renderer/media/android/stream_texture_factory.h"
-#include "content/renderer/media/crypto/proxy_decryptor.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "media/base/android/media_player_android.h"
#include "media/base/demuxer_stream.h"
#include "media/base/media_keys.h"
#include "media/base/time_delta_interpolator.h"
+#include "media/cdm/proxy_decryptor.h"
#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
#include "third_party/WebKit/public/platform/WebMediaPlayer.h"
#include "third_party/WebKit/public/platform/WebSize.h"
@@ -473,7 +473,7 @@ class WebMediaPlayerAndroid : public blink::WebMediaPlayer,
std::string init_data_type_;
// Manages decryption keys and decrypts encrypted frames.
- scoped_ptr<ProxyDecryptor> proxy_decryptor_;
+ scoped_ptr<media::ProxyDecryptor> proxy_decryptor_;
// Non-owned pointer to the CDM. Updated via calls to
// setContentDecryptionModule().
diff --git a/content/renderer/media/crypto/encrypted_media_player_support_impl.cc b/content/renderer/media/crypto/encrypted_media_player_support_impl.cc
deleted file mode 100644
index 86e3329..0000000
--- a/content/renderer/media/crypto/encrypted_media_player_support_impl.cc
+++ /dev/null
@@ -1,475 +0,0 @@
-// Copyright 2014 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/encrypted_media_player_support_impl.h"
-
-#include <string>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/metrics/histogram.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "content/renderer/media/crypto/render_cdm_factory.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/key_systems.h"
-#include "media/blink/encrypted_media_player_support.h"
-#include "media/blink/webcontentdecryptionmodule_impl.h"
-#include "third_party/WebKit/public/platform/WebContentDecryptionModule.h"
-#include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h"
-#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
-#include "third_party/WebKit/public/web/WebDocument.h"
-#include "third_party/WebKit/public/web/WebLocalFrame.h"
-#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
-
-#if defined(ENABLE_PEPPER_CDMS)
-#include "content/renderer/media/crypto/pepper_cdm_wrapper_impl.h"
-#elif defined(ENABLE_BROWSER_CDMS)
-#error Browser side CDM in WMPI for prefixed EME API not supported yet.
-#endif
-
-using blink::WebMediaPlayer;
-using blink::WebMediaPlayerClient;
-using blink::WebString;
-
-namespace content {
-
-#define BIND_TO_RENDER_LOOP(function) \
- (media::BindToCurrentLoop(base::Bind(function, AsWeakPtr())))
-
-#define BIND_TO_RENDER_LOOP1(function, arg1) \
- (media::BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1)))
-
-// Prefix for histograms related to Encrypted Media Extensions.
-static const char* kMediaEme = "Media.EME.";
-
-// Used for calls to decryptor_ready_cb where the result can be ignored.
-static void DoNothing(bool success) {
-}
-
-// Convert a WebString to ASCII, falling back on an empty string in the case
-// of a non-ASCII string.
-static std::string ToASCIIOrEmpty(const WebString& string) {
- return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
- : std::string();
-}
-
-// Helper functions to report media EME related stats to UMA. They follow the
-// convention of more commonly used macros UMA_HISTOGRAM_ENUMERATION and
-// UMA_HISTOGRAM_COUNTS. The reason that we cannot use those macros directly is
-// that UMA_* macros require the names to be constant throughout the process'
-// lifetime.
-static void EmeUMAHistogramEnumeration(const std::string& key_system,
- const std::string& method,
- int sample,
- int boundary_value) {
- base::LinearHistogram::FactoryGet(
- kMediaEme + media::GetKeySystemNameForUMA(key_system) + "." + method,
- 1, boundary_value, boundary_value + 1,
- base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
-}
-
-static void EmeUMAHistogramCounts(const std::string& key_system,
- const std::string& method,
- int sample) {
- // Use the same parameters as UMA_HISTOGRAM_COUNTS.
- base::Histogram::FactoryGet(
- kMediaEme + media::GetKeySystemNameForUMA(key_system) + "." + method,
- 1, 1000000, 50, base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
-}
-
-// Helper enum for reporting generateKeyRequest/addKey histograms.
-enum MediaKeyException {
- kUnknownResultId,
- kSuccess,
- kKeySystemNotSupported,
- kInvalidPlayerState,
- kMaxMediaKeyException
-};
-
-static MediaKeyException MediaKeyExceptionForUMA(
- WebMediaPlayer::MediaKeyException e) {
- switch (e) {
- case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported:
- return kKeySystemNotSupported;
- case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState:
- return kInvalidPlayerState;
- case WebMediaPlayer::MediaKeyExceptionNoError:
- return kSuccess;
- default:
- return kUnknownResultId;
- }
-}
-
-// Helper for converting |key_system| name and exception |e| to a pair of enum
-// values from above, for reporting to UMA.
-static void ReportMediaKeyExceptionToUMA(const std::string& method,
- const std::string& key_system,
- WebMediaPlayer::MediaKeyException e) {
- MediaKeyException result_id = MediaKeyExceptionForUMA(e);
- DCHECK_NE(result_id, kUnknownResultId) << e;
- EmeUMAHistogramEnumeration(
- key_system, method, result_id, kMaxMediaKeyException);
-}
-
-// Guess the type of |init_data|. This is only used to handle some corner cases
-// so we keep it as simple as possible without breaking major use cases.
-static std::string GuessInitDataType(const unsigned char* init_data,
- unsigned init_data_length) {
- // Most WebM files use KeyId of 16 bytes. CENC init data is always >16 bytes.
- if (init_data_length == 16)
- return "webm";
-
- return "cenc";
-}
-
-scoped_ptr<media::EncryptedMediaPlayerSupport>
-EncryptedMediaPlayerSupportImpl::Create(blink::WebMediaPlayerClient* client) {
- return scoped_ptr<EncryptedMediaPlayerSupport>(
- new EncryptedMediaPlayerSupportImpl(client));
-}
-
-EncryptedMediaPlayerSupportImpl::EncryptedMediaPlayerSupportImpl(
- blink::WebMediaPlayerClient* client)
- : client_(client),
- web_cdm_(NULL) {
-}
-
-EncryptedMediaPlayerSupportImpl::~EncryptedMediaPlayerSupportImpl() {
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::GenerateKeyRequest(
- blink::WebLocalFrame* frame,
- const WebString& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) {
- DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": "
- << std::string(reinterpret_cast<const char*>(init_data),
- static_cast<size_t>(init_data_length));
-
- std::string ascii_key_system =
- media::GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
-
- WebMediaPlayer::MediaKeyException e =
- GenerateKeyRequestInternal(frame, ascii_key_system, init_data,
- init_data_length);
- ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::GenerateKeyRequestInternal(
- blink::WebLocalFrame* frame,
- const std::string& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) {
- if (!media::IsConcreteSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- // We do not support run-time switching between key systems for now.
- if (current_key_system_.empty()) {
- if (!proxy_decryptor_) {
- proxy_decryptor_.reset(new ProxyDecryptor(
- BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyAdded),
- BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyError),
- BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyMessage)));
- }
-
- GURL security_origin(frame->document().securityOrigin().toString());
-
-#if defined(ENABLE_PEPPER_CDMS)
- RenderCdmFactory cdm_factory(
- base::Bind(&PepperCdmWrapperImpl::Create, frame));
-#else
- RenderCdmFactory cdm_factory;
-#endif
-
- if (!proxy_decryptor_->InitializeCDM(&cdm_factory, key_system,
- security_origin)) {
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
- }
-
- if (proxy_decryptor_ && !decryptor_ready_cb_.is_null()) {
- base::ResetAndReturn(&decryptor_ready_cb_)
- .Run(proxy_decryptor_->GetDecryptor(), base::Bind(DoNothing));
- }
-
- current_key_system_ = key_system;
- } else if (key_system != current_key_system_) {
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
- }
-
- std::string init_data_type = init_data_type_;
- if (init_data_type.empty())
- init_data_type = GuessInitDataType(init_data, init_data_length);
-
- // TODO(xhwang): We assume all streams are from the same container (thus have
- // the same "type") for now. In the future, the "type" should be passed down
- // from the application.
- if (!proxy_decryptor_->GenerateKeyRequest(
- init_data_type, init_data, init_data_length)) {
- current_key_system_.clear();
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
- }
-
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-WebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupportImpl::AddKey(
- const WebString& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const WebString& session_id) {
- DVLOG(1) << "addKey: " << base::string16(key_system) << ": "
- << std::string(reinterpret_cast<const char*>(key),
- static_cast<size_t>(key_length)) << ", "
- << std::string(reinterpret_cast<const char*>(init_data),
- static_cast<size_t>(init_data_length)) << " ["
- << base::string16(session_id) << "]";
-
- std::string ascii_key_system =
- media::GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
- std::string ascii_session_id = ToASCIIOrEmpty(session_id);
-
- WebMediaPlayer::MediaKeyException e = AddKeyInternal(ascii_key_system,
- key,
- key_length,
- init_data,
- init_data_length,
- ascii_session_id);
- ReportMediaKeyExceptionToUMA("addKey", ascii_key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::AddKeyInternal(
- const std::string& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const std::string& session_id) {
- DCHECK(key);
- DCHECK_GT(key_length, 0u);
-
- if (!media::IsConcreteSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- if (current_key_system_.empty() || key_system != current_key_system_)
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
-
- proxy_decryptor_->AddKey(
- key, key_length, init_data, init_data_length, session_id);
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::CancelKeyRequest(
- const WebString& key_system,
- const WebString& session_id) {
- DVLOG(1) << "cancelKeyRequest: " << base::string16(key_system) << ": "
- << " [" << base::string16(session_id) << "]";
-
- std::string ascii_key_system =
- media::GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
- std::string ascii_session_id = ToASCIIOrEmpty(session_id);
-
- WebMediaPlayer::MediaKeyException e =
- CancelKeyRequestInternal(ascii_key_system, ascii_session_id);
- ReportMediaKeyExceptionToUMA("cancelKeyRequest", ascii_key_system, e);
- return e;
-}
-
-WebMediaPlayer::MediaKeyException
-EncryptedMediaPlayerSupportImpl::CancelKeyRequestInternal(
- const std::string& key_system,
- const std::string& session_id) {
- if (!media::IsConcreteSupportedKeySystem(key_system))
- return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
-
- if (current_key_system_.empty() || key_system != current_key_system_)
- return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
-
- proxy_decryptor_->CancelKeyRequest(session_id);
- return WebMediaPlayer::MediaKeyExceptionNoError;
-}
-
-void EncryptedMediaPlayerSupportImpl::SetInitialContentDecryptionModule(
- blink::WebContentDecryptionModule* initial_cdm) {
- // Used when loading media and no pipeline/decoder attached yet.
- DCHECK(decryptor_ready_cb_.is_null());
-
- web_cdm_ = media::ToWebContentDecryptionModuleImpl(initial_cdm);
-}
-
-void EncryptedMediaPlayerSupportImpl::SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm) {
- // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324
- if (!cdm)
- return;
-
- web_cdm_ = media::ToWebContentDecryptionModuleImpl(cdm);
-
- if (web_cdm_ && !decryptor_ready_cb_.is_null())
- base::ResetAndReturn(&decryptor_ready_cb_)
- .Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
-}
-
-void EncryptedMediaPlayerSupportImpl::SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm,
- blink::WebContentDecryptionModuleResult result) {
- // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324
- if (!cdm) {
- result.completeWithError(
- blink::WebContentDecryptionModuleExceptionNotSupportedError,
- 0,
- "Null MediaKeys object is not supported.");
- return;
- }
-
- web_cdm_ = media::ToWebContentDecryptionModuleImpl(cdm);
-
- if (web_cdm_ && !decryptor_ready_cb_.is_null()) {
- base::ResetAndReturn(&decryptor_ready_cb_)
- .Run(web_cdm_->GetDecryptor(), BIND_TO_RENDER_LOOP1(
- &EncryptedMediaPlayerSupportImpl::ContentDecryptionModuleAttached,
- result));
- } else {
- // No pipeline/decoder connected, so resolve the promise. When something
- // is connected, setting the CDM will happen in SetDecryptorReadyCB().
- ContentDecryptionModuleAttached(result, true);
- }
-}
-
-void EncryptedMediaPlayerSupportImpl::ContentDecryptionModuleAttached(
- blink::WebContentDecryptionModuleResult result,
- bool success) {
- if (success) {
- result.complete();
- return;
- }
-
- result.completeWithError(
- blink::WebContentDecryptionModuleExceptionNotSupportedError,
- 0,
- "Unable to set MediaKeys object");
-}
-
-media::SetDecryptorReadyCB
-EncryptedMediaPlayerSupportImpl::CreateSetDecryptorReadyCB() {
- return BIND_TO_RENDER_LOOP(
- &EncryptedMediaPlayerSupportImpl::SetDecryptorReadyCB);
-}
-
-media::Demuxer::NeedKeyCB
-EncryptedMediaPlayerSupportImpl::CreateNeedKeyCB() {
- return BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnNeedKey);
-}
-
-void EncryptedMediaPlayerSupportImpl::OnPipelineDecryptError() {
- EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1);
-}
-
-void EncryptedMediaPlayerSupportImpl::OnNeedKey(const std::string& type,
- const std::vector<uint8>& init_data) {
- // Do not fire NeedKey event if encrypted media is not enabled.
- if (!blink::WebRuntimeFeatures::isPrefixedEncryptedMediaEnabled() &&
- !blink::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
- return;
- }
-
- UMA_HISTOGRAM_COUNTS(kMediaEme + std::string("NeedKey"), 1);
-
- DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
- if (init_data_type_.empty())
- init_data_type_ = type;
-
- const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
- client_->encrypted(
- WebString::fromUTF8(type), init_data_ptr, init_data.size());
-}
-
-void EncryptedMediaPlayerSupportImpl::OnKeyAdded(
- const std::string& session_id) {
- EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1);
- client_->keyAdded(
- WebString::fromUTF8(media::GetPrefixedKeySystemName(current_key_system_)),
- WebString::fromUTF8(session_id));
-}
-
-void EncryptedMediaPlayerSupportImpl::OnKeyError(const std::string& session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code) {
- EmeUMAHistogramEnumeration(current_key_system_, "KeyError",
- error_code, media::MediaKeys::kMaxKeyError);
-
- uint16 short_system_code = 0;
- if (system_code > std::numeric_limits<uint16>::max()) {
- LOG(WARNING) << "system_code exceeds unsigned short limit.";
- short_system_code = std::numeric_limits<uint16>::max();
- } else {
- short_system_code = static_cast<uint16>(system_code);
- }
-
- client_->keyError(
- WebString::fromUTF8(media::GetPrefixedKeySystemName(current_key_system_)),
- WebString::fromUTF8(session_id),
- static_cast<WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
- short_system_code);
-}
-
-void EncryptedMediaPlayerSupportImpl::OnKeyMessage(
- const std::string& session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url) {
- DCHECK(destination_url.is_empty() || destination_url.is_valid());
-
- client_->keyMessage(
- WebString::fromUTF8(media::GetPrefixedKeySystemName(current_key_system_)),
- WebString::fromUTF8(session_id),
- message.empty() ? NULL : &message[0],
- message.size(),
- destination_url);
-}
-
-void EncryptedMediaPlayerSupportImpl::SetDecryptorReadyCB(
- const media::DecryptorReadyCB& decryptor_ready_cb) {
- // Cancels the previous decryptor request.
- if (decryptor_ready_cb.is_null()) {
- if (!decryptor_ready_cb_.is_null()) {
- base::ResetAndReturn(&decryptor_ready_cb_)
- .Run(NULL, base::Bind(DoNothing));
- }
- return;
- }
-
- // TODO(xhwang): Support multiple decryptor notification request (e.g. from
- // video and audio). The current implementation is okay for the current
- // media pipeline since we initialize audio and video decoders in sequence.
- // But WebMediaPlayerImpl should not depend on media pipeline's implementation
- // detail.
- DCHECK(decryptor_ready_cb_.is_null());
-
- // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink.
- DCHECK(!proxy_decryptor_ || !web_cdm_);
-
- if (proxy_decryptor_) {
- decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor(),
- base::Bind(DoNothing));
- return;
- }
-
- if (web_cdm_) {
- decryptor_ready_cb.Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
- return;
- }
-
- decryptor_ready_cb_ = decryptor_ready_cb;
-}
-
-} // namespace content
diff --git a/content/renderer/media/crypto/encrypted_media_player_support_impl.h b/content/renderer/media/crypto/encrypted_media_player_support_impl.h
deleted file mode 100644
index 88d55d1..0000000
--- a/content/renderer/media/crypto/encrypted_media_player_support_impl.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CONTENT_RENDERER_MEDIA_CRYPTO_ENCRYPTED_MEDIA_PLAYER_SUPPORT_IMPL_H_
-#define CONTENT_RENDERER_MEDIA_CRYPTO_ENCRYPTED_MEDIA_PLAYER_SUPPORT_IMPL_H_
-
-#include <string>
-#include <vector>
-
-#include "base/memory/weak_ptr.h"
-#include "content/renderer/media/crypto/proxy_decryptor.h"
-#include "media/blink/encrypted_media_player_support.h"
-#include "media/blink/webcontentdecryptionmodule_impl.h"
-
-namespace blink {
-class WebMediaPlayerClient;
-}
-
-namespace content {
-
-class WebContentDecryptionModuleImpl;
-
-class EncryptedMediaPlayerSupportImpl
- : public media::EncryptedMediaPlayerSupport,
- public base::SupportsWeakPtr<EncryptedMediaPlayerSupportImpl> {
- public:
- static scoped_ptr<EncryptedMediaPlayerSupport> Create(
- blink::WebMediaPlayerClient* client);
-
- ~EncryptedMediaPlayerSupportImpl() override;
-
- // EncryptedMediaPlayerSupport implementation.
- blink::WebMediaPlayer::MediaKeyException GenerateKeyRequest(
- blink::WebLocalFrame* frame,
- const blink::WebString& key_system,
- const unsigned char* init_data,
- unsigned init_data_length) override;
-
- blink::WebMediaPlayer::MediaKeyException AddKey(
- const blink::WebString& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const blink::WebString& session_id) override;
-
- blink::WebMediaPlayer::MediaKeyException CancelKeyRequest(
- const blink::WebString& key_system,
- const blink::WebString& session_id) override;
-
- void SetInitialContentDecryptionModule(
- blink::WebContentDecryptionModule* initial_cdm) override;
-
- void SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm) override;
- void SetContentDecryptionModule(
- blink::WebContentDecryptionModule* cdm,
- blink::WebContentDecryptionModuleResult result) override;
-
- media::SetDecryptorReadyCB CreateSetDecryptorReadyCB() override;
- media::Demuxer::NeedKeyCB CreateNeedKeyCB() override;
-
- void OnPipelineDecryptError() override;
-
- private:
- explicit EncryptedMediaPlayerSupportImpl(blink::WebMediaPlayerClient* client);
-
- // Requests that this object notifies when a decryptor is ready through the
- // |decryptor_ready_cb| provided.
- // If |decryptor_ready_cb| is null, the existing callback will be fired with
- // NULL immediately and reset.
- void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb);
-
- blink::WebMediaPlayer::MediaKeyException GenerateKeyRequestInternal(
- blink::WebLocalFrame* frame,
- const std::string& key_system,
- const unsigned char* init_data,
- unsigned init_data_length);
-
- blink::WebMediaPlayer::MediaKeyException AddKeyInternal(
- const std::string& key_system,
- const unsigned char* key,
- unsigned key_length,
- const unsigned char* init_data,
- unsigned init_data_length,
- const std::string& session_id);
-
- blink::WebMediaPlayer::MediaKeyException CancelKeyRequestInternal(
- const std::string& key_system,
- const std::string& session_id);
-
- void OnNeedKey(const std::string& type,
- const std::vector<uint8>& init_data);
-
- void OnKeyAdded(const std::string& session_id);
- void OnKeyError(const std::string& session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code);
- void OnKeyMessage(const std::string& session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url);
-
- void ContentDecryptionModuleAttached(
- blink::WebContentDecryptionModuleResult result,
- bool success);
-
- blink::WebMediaPlayerClient* client_;
-
- // The currently selected key system. Empty string means that no key system
- // has been selected.
- std::string current_key_system_;
-
- // Temporary for EME v0.1. In the future the init data type should be passed
- // through GenerateKeyRequest() directly from WebKit.
- std::string init_data_type_;
-
- // Manages decryption keys and decrypts encrypted frames.
- scoped_ptr<ProxyDecryptor> proxy_decryptor_;
-
- // Non-owned pointer to the CDM. Updated via calls to
- // setContentDecryptionModule().
- media::WebContentDecryptionModuleImpl* web_cdm_;
-
- media::DecryptorReadyCB decryptor_ready_cb_;
-
- DISALLOW_COPY_AND_ASSIGN(EncryptedMediaPlayerSupportImpl);
-};
-}
-
-#endif // CONTENT_RENDERER_MEDIA_CRYPTO_ENCRYPTED_MEDIA_PLAYER_SUPPORT_IMPL_H_
diff --git a/content/renderer/media/crypto/proxy_decryptor.cc b/content/renderer/media/crypto/proxy_decryptor.cc
deleted file mode 100644
index 44a30fd..0000000
--- a/content/renderer/media/crypto/proxy_decryptor.cc
+++ /dev/null
@@ -1,312 +0,0 @@
-// 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/proxy_decryptor.h"
-
-#include <cstring>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-#include "base/strings/string_util.h"
-#include "media/base/cdm_callback_promise.h"
-#include "media/base/cdm_factory.h"
-#include "media/cdm/json_web_key.h"
-#include "media/cdm/key_system_names.h"
-
-namespace content {
-
-// Special system code to signal a closed persistent session in a SessionError()
-// call. This is needed because there is no SessionClosed() call in the prefixed
-// EME API.
-const int kSessionClosedSystemCode = 29127;
-
-ProxyDecryptor::ProxyDecryptor(const KeyAddedCB& key_added_cb,
- const KeyErrorCB& key_error_cb,
- const KeyMessageCB& key_message_cb)
- : key_added_cb_(key_added_cb),
- key_error_cb_(key_error_cb),
- key_message_cb_(key_message_cb),
- is_clear_key_(false),
- weak_ptr_factory_(this) {
- DCHECK(!key_added_cb_.is_null());
- DCHECK(!key_error_cb_.is_null());
- DCHECK(!key_message_cb_.is_null());
-}
-
-ProxyDecryptor::~ProxyDecryptor() {
- // Destroy the decryptor explicitly before destroying the plugin.
- media_keys_.reset();
-}
-
-media::Decryptor* ProxyDecryptor::GetDecryptor() {
- return media_keys_ ? media_keys_->GetDecryptor() : NULL;
-}
-
-#if defined(ENABLE_BROWSER_CDMS)
-int ProxyDecryptor::GetCdmId() {
- return media_keys_->GetCdmId();
-}
-#endif
-
-bool ProxyDecryptor::InitializeCDM(media::CdmFactory* cdm_factory,
- const std::string& key_system,
- const GURL& security_origin) {
- DVLOG(1) << "InitializeCDM: key_system = " << key_system;
-
- DCHECK(!media_keys_);
- media_keys_ = CreateMediaKeys(cdm_factory, key_system, security_origin);
- if (!media_keys_)
- return false;
-
- is_clear_key_ =
- media::IsClearKey(key_system) || media::IsExternalClearKey(key_system);
- return true;
-}
-
-// Returns true if |data| is prefixed with |header| and has data after the
-// |header|.
-bool HasHeader(const uint8* data, int data_length, const std::string& header) {
- return static_cast<size_t>(data_length) > header.size() &&
- std::equal(data, data + header.size(), header.begin());
-}
-
-// Removes the first |length| items from |data|.
-void StripHeader(std::vector<uint8>& data, size_t length) {
- data.erase(data.begin(), data.begin() + length);
-}
-
-bool ProxyDecryptor::GenerateKeyRequest(const std::string& init_data_type,
- const uint8* init_data,
- int init_data_length) {
- DVLOG(1) << "GenerateKeyRequest()";
- const char kPrefixedApiPersistentSessionHeader[] = "PERSISTENT|";
- const char kPrefixedApiLoadSessionHeader[] = "LOAD_SESSION|";
-
- SessionCreationType session_creation_type = TemporarySession;
- std::vector<uint8> init_data_vector(init_data, init_data + init_data_length);
- if (HasHeader(init_data, init_data_length, kPrefixedApiLoadSessionHeader)) {
- session_creation_type = LoadSession;
- StripHeader(init_data_vector, strlen(kPrefixedApiLoadSessionHeader));
- } else if (HasHeader(init_data,
- init_data_length,
- kPrefixedApiPersistentSessionHeader)) {
- session_creation_type = PersistentSession;
- StripHeader(init_data_vector, strlen(kPrefixedApiPersistentSessionHeader));
- }
-
- scoped_ptr<media::NewSessionCdmPromise> promise(
- new media::CdmCallbackPromise<std::string>(
- base::Bind(&ProxyDecryptor::SetSessionId,
- weak_ptr_factory_.GetWeakPtr(),
- session_creation_type),
- base::Bind(&ProxyDecryptor::OnSessionError,
- weak_ptr_factory_.GetWeakPtr(),
- std::string()))); // No session id until created.
- uint8* init_data_vector_data =
- (init_data_vector.size() > 0) ? &init_data_vector[0] : nullptr;
-
- if (session_creation_type == LoadSession) {
- media_keys_->LoadSession(
- std::string(reinterpret_cast<const char*>(init_data_vector_data),
- init_data_vector.size()),
- promise.Pass());
- return true;
- }
-
- media::MediaKeys::SessionType session_type =
- session_creation_type == PersistentSession
- ? media::MediaKeys::PERSISTENT_SESSION
- : media::MediaKeys::TEMPORARY_SESSION;
-
- media_keys_->CreateSession(init_data_type,
- init_data_vector_data,
- init_data_vector.size(),
- session_type,
- promise.Pass());
- return true;
-}
-
-void ProxyDecryptor::AddKey(const uint8* key,
- int key_length,
- const uint8* init_data,
- int init_data_length,
- const std::string& web_session_id) {
- DVLOG(1) << "AddKey()";
-
- // In the prefixed API, the session parameter provided to addKey() is
- // optional, so use the single existing session if it exists.
- // TODO(jrummell): remove when the prefixed API is removed.
- std::string session_id(web_session_id);
- if (session_id.empty()) {
- if (active_sessions_.size() == 1) {
- base::hash_map<std::string, bool>::iterator it = active_sessions_.begin();
- session_id = it->first;
- } else {
- OnSessionError(std::string(),
- media::MediaKeys::NOT_SUPPORTED_ERROR,
- 0,
- "SessionId not specified.");
- return;
- }
- }
-
- scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>(
- base::Bind(&ProxyDecryptor::OnSessionReady,
- weak_ptr_factory_.GetWeakPtr(),
- web_session_id),
- base::Bind(&ProxyDecryptor::OnSessionError,
- weak_ptr_factory_.GetWeakPtr(),
- web_session_id)));
-
- // EME WD spec only supports a single array passed to the CDM. For
- // Clear Key using v0.1b, both arrays are used (|init_data| is key_id).
- // Since the EME WD spec supports the key as a JSON Web Key,
- // convert the 2 arrays to a JWK and pass it as the single array.
- if (is_clear_key_) {
- // Decryptor doesn't support empty key ID (see http://crbug.com/123265).
- // So ensure a non-empty value is passed.
- if (!init_data) {
- static const uint8 kDummyInitData[1] = {0};
- init_data = kDummyInitData;
- init_data_length = arraysize(kDummyInitData);
- }
-
- std::string jwk =
- media::GenerateJWKSet(key, key_length, init_data, init_data_length);
- DCHECK(!jwk.empty());
- media_keys_->UpdateSession(session_id,
- reinterpret_cast<const uint8*>(jwk.data()),
- jwk.size(),
- promise.Pass());
- return;
- }
-
- media_keys_->UpdateSession(session_id, key, key_length, promise.Pass());
-}
-
-void ProxyDecryptor::CancelKeyRequest(const std::string& web_session_id) {
- DVLOG(1) << "CancelKeyRequest()";
-
- scoped_ptr<media::SimpleCdmPromise> promise(new media::CdmCallbackPromise<>(
- base::Bind(&ProxyDecryptor::OnSessionClosed,
- weak_ptr_factory_.GetWeakPtr(),
- web_session_id),
- base::Bind(&ProxyDecryptor::OnSessionError,
- weak_ptr_factory_.GetWeakPtr(),
- web_session_id)));
- media_keys_->RemoveSession(web_session_id, promise.Pass());
-}
-
-scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys(
- media::CdmFactory* cdm_factory,
- const std::string& key_system,
- const GURL& security_origin) {
- base::WeakPtr<ProxyDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr();
- return cdm_factory->Create(
- key_system,
- security_origin,
- base::Bind(&ProxyDecryptor::OnSessionMessage, weak_this),
- base::Bind(&ProxyDecryptor::OnSessionReady, weak_this),
- base::Bind(&ProxyDecryptor::OnSessionClosed, weak_this),
- base::Bind(&ProxyDecryptor::OnSessionError, weak_this),
- base::Bind(&ProxyDecryptor::OnSessionKeysChange, weak_this),
- base::Bind(&ProxyDecryptor::OnSessionExpirationUpdate, weak_this));
-}
-
-void ProxyDecryptor::OnSessionMessage(const std::string& web_session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url) {
- // Assumes that OnSessionCreated() has been called before this.
-
- // For ClearKey, convert the message from JSON into just passing the key
- // as the message. If unable to extract the key, return the message unchanged.
- if (is_clear_key_) {
- std::vector<uint8> key;
- if (media::ExtractFirstKeyIdFromLicenseRequest(message, &key)) {
- key_message_cb_.Run(web_session_id, key, destination_url);
- return;
- }
- }
-
- key_message_cb_.Run(web_session_id, message, destination_url);
-}
-
-void ProxyDecryptor::OnSessionKeysChange(const std::string& web_session_id,
- bool has_additional_usable_key) {
- // EME v0.1b doesn't support this event.
-}
-
-void ProxyDecryptor::OnSessionExpirationUpdate(
- const std::string& web_session_id,
- const base::Time& new_expiry_time) {
- // EME v0.1b doesn't support this event.
-}
-
-void ProxyDecryptor::OnSessionReady(const std::string& web_session_id) {
- key_added_cb_.Run(web_session_id);
-}
-
-void ProxyDecryptor::OnSessionClosed(const std::string& web_session_id) {
- base::hash_map<std::string, bool>::iterator it =
- active_sessions_.find(web_session_id);
-
- // Latest EME spec separates closing a session ("allows an application to
- // indicate that it no longer needs the session") and actually closing the
- // session (done by the CDM at any point "such as in response to a close()
- // call, when the session is no longer needed, or when system resources are
- // lost.") Thus the CDM may cause 2 close() events -- one to resolve the
- // close() promise, and a second to actually close the session. Prefixed EME
- // only expects 1 close event, so drop the second (and subsequent) events.
- // However, this means we can't tell if the CDM is generating spurious close()
- // events.
- if (it == active_sessions_.end())
- return;
-
- if (it->second) {
- OnSessionError(web_session_id,
- media::MediaKeys::NOT_SUPPORTED_ERROR,
- kSessionClosedSystemCode,
- "Do not close persistent sessions.");
- }
- active_sessions_.erase(it);
-}
-
-void ProxyDecryptor::OnSessionError(const std::string& web_session_id,
- media::MediaKeys::Exception exception_code,
- uint32 system_code,
- const std::string& error_message) {
- // Convert |error_name| back to MediaKeys::KeyError if possible. Prefixed
- // EME has different error message, so all the specific error events will
- // get lost.
- media::MediaKeys::KeyError error_code;
- switch (exception_code) {
- case media::MediaKeys::CLIENT_ERROR:
- error_code = media::MediaKeys::kClientError;
- break;
- case media::MediaKeys::OUTPUT_ERROR:
- error_code = media::MediaKeys::kOutputError;
- break;
- default:
- // This will include all other CDM4 errors and any error generated
- // by CDM5 or later.
- error_code = media::MediaKeys::kUnknownError;
- break;
- }
- key_error_cb_.Run(web_session_id, error_code, system_code);
-}
-
-void ProxyDecryptor::SetSessionId(SessionCreationType session_type,
- const std::string& web_session_id) {
- // Loaded sessions are considered persistent.
- bool is_persistent =
- session_type == PersistentSession || session_type == LoadSession;
- active_sessions_.insert(std::make_pair(web_session_id, is_persistent));
-
- // For LoadSession(), generate the SessionReady event.
- if (session_type == LoadSession)
- OnSessionReady(web_session_id);
-}
-
-} // namespace content
diff --git a/content/renderer/media/crypto/proxy_decryptor.h b/content/renderer/media/crypto/proxy_decryptor.h
deleted file mode 100644
index 62f2e8e..0000000
--- a/content/renderer/media/crypto/proxy_decryptor.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// 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.
-
-#ifndef CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
-#define CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/containers/hash_tables.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "media/base/decryptor.h"
-#include "media/base/media_keys.h"
-
-class GURL;
-
-namespace media {
-class CdmFactory;
-}
-
-namespace content {
-
-// ProxyDecryptor is for EME v0.1b only. It should not be used for the WD API.
-// A decryptor proxy that creates a real decryptor object on demand and
-// forwards decryptor calls to it.
-//
-// TODO(xhwang): Currently we don't support run-time switching among decryptor
-// objects. Fix this when needed.
-// TODO(xhwang): The ProxyDecryptor is not a Decryptor. Find a better name!
-class ProxyDecryptor {
- public:
- // These are similar to the callbacks in media_keys.h, but pass back the
- // web session ID rather than the internal session ID.
- typedef base::Callback<void(const std::string& session_id)> KeyAddedCB;
- typedef base::Callback<void(const std::string& session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code)> KeyErrorCB;
- typedef base::Callback<void(const std::string& session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url)> KeyMessageCB;
-
- ProxyDecryptor(const KeyAddedCB& key_added_cb,
- const KeyErrorCB& key_error_cb,
- const KeyMessageCB& key_message_cb);
- virtual ~ProxyDecryptor();
-
- // Returns the Decryptor associated with this object. May be NULL if no
- // Decryptor is associated.
- media::Decryptor* GetDecryptor();
-
-#if defined(ENABLE_BROWSER_CDMS)
- // Returns the CDM ID associated with this object. May be kInvalidCdmId if no
- // CDM ID is associated, such as when Clear Key is used.
- int GetCdmId();
-#endif
-
- // Only call this once.
- bool InitializeCDM(media::CdmFactory* cdm_factory,
- const std::string& key_system,
- const GURL& security_origin);
-
- // May only be called after InitializeCDM() succeeds.
- bool GenerateKeyRequest(const std::string& init_data_type,
- const uint8* init_data,
- int init_data_length);
- void AddKey(const uint8* key, int key_length,
- const uint8* init_data, int init_data_length,
- const std::string& session_id);
- void CancelKeyRequest(const std::string& session_id);
-
- private:
- // Helper function to create MediaKeys to handle the given |key_system|.
- scoped_ptr<media::MediaKeys> CreateMediaKeys(
- media::CdmFactory* cdm_factory,
- const std::string& key_system,
- const GURL& security_origin);
-
- // Callbacks for firing session events.
- void OnSessionMessage(const std::string& web_session_id,
- const std::vector<uint8>& message,
- const GURL& default_url);
- void OnSessionKeysChange(const std::string& web_session_id,
- bool has_additional_usable_key);
- void OnSessionExpirationUpdate(const std::string& web_session_id,
- const base::Time& new_expiry_time);
- void OnSessionReady(const std::string& web_session_id);
- void OnSessionClosed(const std::string& web_session_id);
- void OnSessionError(const std::string& web_session_id,
- media::MediaKeys::Exception exception_code,
- uint32 system_code,
- const std::string& error_message);
-
- enum SessionCreationType {
- TemporarySession,
- PersistentSession,
- LoadSession
- };
-
- // Called when a session is actually created or loaded.
- void SetSessionId(SessionCreationType session_type,
- const std::string& web_session_id);
-
- // The real MediaKeys that manages key operations for the ProxyDecryptor.
- scoped_ptr<media::MediaKeys> media_keys_;
-
- // Callbacks for firing key events.
- KeyAddedCB key_added_cb_;
- KeyErrorCB key_error_cb_;
- KeyMessageCB key_message_cb_;
-
- // Keep track of both persistent and non-persistent sessions.
- base::hash_map<std::string, bool> active_sessions_;
-
- bool is_clear_key_;
-
-#if defined(ENABLE_BROWSER_CDMS)
- int cdm_id_;
-#endif
-
- // NOTE: Weak pointers must be invalidated before all other member variables.
- base::WeakPtrFactory<ProxyDecryptor> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ProxyDecryptor);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 8e70202..8678b58 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -70,7 +70,6 @@
#include "content/renderer/internal_document_state_data.h"
#include "content/renderer/manifest/manifest_manager.h"
#include "content/renderer/media/audio_renderer_mixer_manager.h"
-#include "content/renderer/media/crypto/encrypted_media_player_support_impl.h"
#include "content/renderer/media/crypto/render_cdm_factory.h"
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/media_stream_renderer_factory.h"
@@ -97,6 +96,7 @@
#include "gin/modules/module_registry.h"
#include "media/base/audio_renderer_mixer_input.h"
#include "media/base/renderer.h"
+#include "media/blink/encrypted_media_player_support.h"
#include "media/blink/webcontentdecryptionmodule_impl.h"
#include "media/blink/webmediaplayer_impl.h"
#include "media/blink/webmediaplayer_params.h"
@@ -1773,15 +1773,22 @@ blink::WebMediaPlayer* RenderFrameImpl::createMediaPlayer(
render_thread->GetGpuFactories(),
render_thread->GetMediaThreadTaskRunner(),
render_thread->compositor_message_loop_proxy(),
- base::Bind(&EncryptedMediaPlayerSupportImpl::Create),
initial_cdm);
+#if defined(ENABLE_PEPPER_CDMS)
+ scoped_ptr<media::CdmFactory> cdm_factory(
+ new RenderCdmFactory(base::Bind(&PepperCdmWrapperImpl::Create, frame)));
+#else
+ scoped_ptr<media::CdmFactory> cdm_factory(new RenderCdmFactory());
+#endif
+
scoped_ptr<media::Renderer> media_renderer =
GetContentClient()->renderer()->CreateMediaRenderer(
this, render_thread->GetMediaThreadTaskRunner());
return new media::WebMediaPlayerImpl(
- frame, client, weak_factory_.GetWeakPtr(), media_renderer.Pass(), params);
+ frame, client, weak_factory_.GetWeakPtr(), media_renderer.Pass(),
+ cdm_factory.Pass(), params);
#endif // defined(OS_ANDROID)
}