summaryrefslogtreecommitdiff
path: root/chromium/content/renderer/media/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/renderer/media/crypto')
-rw-r--r--chromium/content/renderer/media/crypto/cdm_initialized_promise.cc30
-rw-r--r--chromium/content/renderer/media/crypto/cdm_initialized_promise.h39
-rw-r--r--chromium/content/renderer/media/crypto/encrypted_media_player_support_impl.cc475
-rw-r--r--chromium/content/renderer/media/crypto/encrypted_media_player_support_impl.h130
-rw-r--r--chromium/content/renderer/media/crypto/key_systems.cc650
-rw-r--r--chromium/content/renderer/media/crypto/key_systems.h80
-rw-r--r--chromium/content/renderer/media/crypto/key_systems_support_uma.cc136
-rw-r--r--chromium/content/renderer/media/crypto/key_systems_support_uma.h57
-rw-r--r--chromium/content/renderer/media/crypto/key_systems_unittest.cc649
-rw-r--r--chromium/content/renderer/media/crypto/ppapi_decryptor.cc177
-rw-r--r--chromium/content/renderer/media/crypto/ppapi_decryptor.h84
-rw-r--r--chromium/content/renderer/media/crypto/proxy_decryptor.cc312
-rw-r--r--chromium/content/renderer/media/crypto/proxy_decryptor.h131
-rw-r--r--chromium/content/renderer/media/crypto/proxy_media_keys.cc326
-rw-r--r--chromium/content/renderer/media/crypto/proxy_media_keys.h149
-rw-r--r--chromium/content/renderer/media/crypto/render_cdm_factory.cc104
-rw-r--r--chromium/content/renderer/media/crypto/render_cdm_factory.h31
-rw-r--r--chromium/content/renderer/media/crypto/renderer_cdm_manager.cc163
-rw-r--r--chromium/content/renderer/media/crypto/renderer_cdm_manager.h65
19 files changed, 640 insertions, 3148 deletions
diff --git a/chromium/content/renderer/media/crypto/cdm_initialized_promise.cc b/chromium/content/renderer/media/crypto/cdm_initialized_promise.cc
new file mode 100644
index 00000000000..8d9b7afd631
--- /dev/null
+++ b/chromium/content/renderer/media/crypto/cdm_initialized_promise.cc
@@ -0,0 +1,30 @@
+// Copyright 2015 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/cdm_initialized_promise.h"
+
+namespace content {
+
+CdmInitializedPromise::CdmInitializedPromise(
+ const media::CdmCreatedCB& cdm_created_cb,
+ scoped_ptr<media::MediaKeys> cdm)
+ : cdm_created_cb_(cdm_created_cb), cdm_(cdm.Pass()) {
+}
+
+CdmInitializedPromise::~CdmInitializedPromise() {
+}
+
+void CdmInitializedPromise::resolve() {
+ MarkPromiseSettled();
+ cdm_created_cb_.Run(cdm_.Pass(), "");
+}
+
+void CdmInitializedPromise::reject(media::MediaKeys::Exception exception_code,
+ uint32 system_code,
+ const std::string& error_message) {
+ MarkPromiseSettled();
+ cdm_created_cb_.Run(nullptr, error_message);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/crypto/cdm_initialized_promise.h b/chromium/content/renderer/media/crypto/cdm_initialized_promise.h
new file mode 100644
index 00000000000..7c3d4c38116
--- /dev/null
+++ b/chromium/content/renderer/media/crypto/cdm_initialized_promise.h
@@ -0,0 +1,39 @@
+// Copyright 2015 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_CDM_INITIALIZED_PROMISE_H_
+#define CONTENT_RENDERER_MEDIA_CRYPTO_CDM_INITIALIZED_PROMISE_H_
+
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "media/base/cdm_factory.h"
+#include "media/base/cdm_promise.h"
+#include "media/base/media_keys.h"
+
+namespace content {
+
+// Promise to be resolved when the CDM is initialized. It owns the MediaKeys
+// object until the initialization completes, which it then passes to
+// |cdm_created_cb|.
+class CdmInitializedPromise : public media::SimpleCdmPromise {
+ public:
+ CdmInitializedPromise(const media::CdmCreatedCB& cdm_created_cb,
+ scoped_ptr<media::MediaKeys> cdm);
+ ~CdmInitializedPromise() override;
+
+ // SimpleCdmPromise implementation.
+ void resolve() override;
+ void reject(media::MediaKeys::Exception exception_code,
+ uint32 system_code,
+ const std::string& error_message) override;
+
+ private:
+ media::CdmCreatedCB cdm_created_cb_;
+ scoped_ptr<media::MediaKeys> cdm_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_CRYPTO_CDM_INITIALIZED_PROMISE_H_
diff --git a/chromium/content/renderer/media/crypto/encrypted_media_player_support_impl.cc b/chromium/content/renderer/media/crypto/encrypted_media_player_support_impl.cc
deleted file mode 100644
index cf24056f14f..00000000000
--- a/chromium/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/key_systems.h"
-#include "content/renderer/media/crypto/render_cdm_factory.h"
-#include "content/renderer/media/webcontentdecryptionmodule_impl.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/blink/encrypted_media_player_support.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 + KeySystemNameForUMA(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 + KeySystemNameForUMA(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 =
- 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 (!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 =
- 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 (!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 =
- 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 (!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_ = 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_ = 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_ = 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(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(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(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/chromium/content/renderer/media/crypto/encrypted_media_player_support_impl.h b/chromium/content/renderer/media/crypto/encrypted_media_player_support_impl.h
deleted file mode 100644
index d68d40b7d5a..00000000000
--- a/chromium/content/renderer/media/crypto/encrypted_media_player_support_impl.h
+++ /dev/null
@@ -1,130 +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"
-
-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().
- 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/chromium/content/renderer/media/crypto/key_systems.cc b/chromium/content/renderer/media/crypto/key_systems.cc
deleted file mode 100644
index 9c3ce046ab6..00000000000
--- a/chromium/content/renderer/media/crypto/key_systems.cc
+++ /dev/null
@@ -1,650 +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/key_systems.h"
-
-#include <string>
-
-#include "base/containers/hash_tables.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/strings/string_util.h"
-#include "base/threading/thread_checker.h"
-#include "base/time/time.h"
-#include "content/public/common/content_client.h"
-#include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/media/crypto/key_systems_support_uma.h"
-#include "media/base/eme_constants.h"
-#include "media/base/key_system_info.h"
-
-#if defined(OS_ANDROID)
-#include "media/base/android/media_codec_bridge.h"
-#endif
-
-#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
-
-namespace content {
-
-using media::EmeCodec;
-using media::EmeInitDataType;
-using media::KeySystemInfo;
-using media::SupportedInitDataTypes;
-using media::SupportedCodecs;
-
-const char kClearKeyKeySystem[] = "org.w3.clearkey";
-const char kPrefixedClearKeyKeySystem[] = "webkit-org.w3.clearkey";
-const char kUnsupportedClearKeyKeySystem[] = "unsupported-org.w3.clearkey";
-
-struct NamedInitDataType {
- const char* name;
- EmeInitDataType type;
-};
-
-// Mapping between initialization data types names and enum values. When adding
-// entries, make sure to update IsSaneInitDataTypeWithContainer().
-static NamedInitDataType kInitDataTypeNames[] = {
- {"webm", media::EME_INIT_DATA_TYPE_WEBM},
-#if defined(USE_PROPRIETARY_CODECS)
- {"cenc", media::EME_INIT_DATA_TYPE_CENC}
-#endif // defined(USE_PROPRIETARY_CODECS)
-};
-
-struct NamedCodec {
- const char* name;
- EmeCodec type;
-};
-
-// Mapping between containers and their codecs.
-// Only audio codec can belong to a "audio/*" container. Both audio and video
-// codecs can belong to a "video/*" container.
-static NamedCodec kContainerToCodecMasks[] = {
- {"audio/webm", media::EME_CODEC_WEBM_AUDIO_ALL},
- {"video/webm", media::EME_CODEC_WEBM_ALL},
-#if defined(USE_PROPRIETARY_CODECS)
- {"audio/mp4", media::EME_CODEC_MP4_AUDIO_ALL},
- {"video/mp4", media::EME_CODEC_MP4_ALL}
-#endif // defined(USE_PROPRIETARY_CODECS)
-};
-
-// Mapping between codec names and enum values.
-static NamedCodec kCodecStrings[] = {
- {"vorbis", media::EME_CODEC_WEBM_VORBIS},
- {"vp8", media::EME_CODEC_WEBM_VP8},
- {"vp8.0", media::EME_CODEC_WEBM_VP8},
- {"vp9", media::EME_CODEC_WEBM_VP9},
- {"vp9.0", media::EME_CODEC_WEBM_VP9},
-#if defined(USE_PROPRIETARY_CODECS)
- {"mp4a", media::EME_CODEC_MP4_AAC},
- {"avc1", media::EME_CODEC_MP4_AVC1},
- {"avc3", media::EME_CODEC_MP4_AVC1}
-#endif // defined(USE_PROPRIETARY_CODECS)
-};
-
-static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) {
- KeySystemInfo info(kClearKeyKeySystem);
-
- // On Android, Vorbis, VP8, AAC and AVC1 are supported in MediaCodec:
- // http://developer.android.com/guide/appendix/media-formats.html
- // VP9 support is device dependent.
-
- info.supported_init_data_types = media::EME_INIT_DATA_TYPE_WEBM;
- info.supported_codecs = media::EME_CODEC_WEBM_ALL;
-
-#if defined(OS_ANDROID)
- // Temporarily disable VP9 support for Android.
- // TODO(xhwang): Use mime_util.h to query VP9 support on Android.
- info.supported_codecs &= ~media::EME_CODEC_WEBM_VP9;
-#endif // defined(OS_ANDROID)
-
-#if defined(USE_PROPRIETARY_CODECS)
- info.supported_init_data_types |= media::EME_INIT_DATA_TYPE_CENC;
- info.supported_codecs |= media::EME_CODEC_MP4_ALL;
-#endif // defined(USE_PROPRIETARY_CODECS)
-
- info.use_aes_decryptor = true;
-
- concrete_key_systems->push_back(info);
-}
-
-class KeySystems {
- public:
- static KeySystems& GetInstance();
-
- void UpdateIfNeeded();
-
- bool IsConcreteSupportedKeySystem(const std::string& key_system);
-
- bool IsSupportedKeySystem(const std::string& key_system);
-
- bool IsSupportedKeySystemWithInitDataType(
- const std::string& key_system,
- const std::string& init_data_type);
-
- bool IsSupportedKeySystemWithMediaMimeType(
- const std::string& mime_type,
- const std::vector<std::string>& codecs,
- const std::string& key_system);
-
- bool UseAesDecryptor(const std::string& concrete_key_system);
-
-#if defined(ENABLE_PEPPER_CDMS)
- std::string GetPepperType(const std::string& concrete_key_system);
-#endif
-
- void AddContainerMask(const std::string& container, uint32 mask);
- void AddCodecMask(const std::string& codec, uint32 mask);
-
- private:
- void UpdateSupportedKeySystems();
-
- void AddConcreteSupportedKeySystems(
- const std::vector<KeySystemInfo>& concrete_key_systems);
-
- void AddConcreteSupportedKeySystem(
- const std::string& key_system,
- bool use_aes_decryptor,
-#if defined(ENABLE_PEPPER_CDMS)
- const std::string& pepper_type,
-#endif
- SupportedInitDataTypes supported_init_data_types,
- SupportedCodecs supported_codecs,
- const std::string& parent_key_system);
-
- friend struct base::DefaultLazyInstanceTraits<KeySystems>;
-
- struct KeySystemProperties {
- KeySystemProperties()
- : use_aes_decryptor(false), supported_codecs(media::EME_CODEC_NONE) {}
-
- bool use_aes_decryptor;
-#if defined(ENABLE_PEPPER_CDMS)
- std::string pepper_type;
-#endif
- SupportedInitDataTypes supported_init_data_types;
- SupportedCodecs supported_codecs;
- };
-
- typedef base::hash_map<std::string, KeySystemProperties>
- KeySystemPropertiesMap;
- typedef base::hash_map<std::string, std::string> ParentKeySystemMap;
- typedef base::hash_map<std::string, SupportedCodecs> ContainerCodecsMap;
- typedef base::hash_map<std::string, EmeCodec> CodecsMap;
- typedef base::hash_map<std::string, media::EmeInitDataType> InitDataTypesMap;
-
- KeySystems();
- ~KeySystems() {}
-
- EmeInitDataType GetInitDataTypeForName(
- const std::string& init_data_type) const;
- // TODO(sandersd): Separate container enum from codec mask value.
- // http://crbug.com/417440
- SupportedCodecs GetCodecMaskForContainer(
- const std::string& container) const;
- EmeCodec GetCodecForString(const std::string& codec) const;
-
- const std::string& GetConcreteKeySystemName(
- const std::string& key_system) const;
-
- // Returns whether a |container| type is supported by checking
- // |key_system_supported_codecs|.
- // TODO(xhwang): Update this to actually check initDataType support.
- bool IsSupportedContainer(const std::string& container,
- SupportedCodecs key_system_supported_codecs) const;
-
- // Returns true if all |codecs| are supported in |container| by checking
- // |key_system_supported_codecs|.
- bool IsSupportedContainerAndCodecs(
- const std::string& container,
- const std::vector<std::string>& codecs,
- SupportedCodecs key_system_supported_codecs) const;
-
- // Map from key system string to capabilities.
- KeySystemPropertiesMap concrete_key_system_map_;
-
- // Map from parent key system to the concrete key system that should be used
- // to represent its capabilities.
- ParentKeySystemMap parent_key_system_map_;
-
- KeySystemsSupportUMA key_systems_support_uma_;
-
- InitDataTypesMap init_data_type_name_map_;
- ContainerCodecsMap container_to_codec_mask_map_;
- CodecsMap codec_string_map_;
-
- bool needs_update_;
- base::Time last_update_time_;
-
- // Makes sure all methods are called from the same thread.
- base::ThreadChecker thread_checker_;
-
- DISALLOW_COPY_AND_ASSIGN(KeySystems);
-};
-
-static base::LazyInstance<KeySystems> g_key_systems = LAZY_INSTANCE_INITIALIZER;
-
-KeySystems& KeySystems::GetInstance() {
- KeySystems& key_systems = g_key_systems.Get();
- key_systems.UpdateIfNeeded();
- return key_systems;
-}
-
-// Because we use a LazyInstance, the key systems info must be populated when
-// the instance is lazily initiated.
-KeySystems::KeySystems() : needs_update_(true) {
- for (size_t i = 0; i < arraysize(kInitDataTypeNames); ++i) {
- const std::string& name = kInitDataTypeNames[i].name;
- DCHECK(!init_data_type_name_map_.count(name));
- init_data_type_name_map_[name] = kInitDataTypeNames[i].type;
- }
- for (size_t i = 0; i < arraysize(kContainerToCodecMasks); ++i) {
- const std::string& name = kContainerToCodecMasks[i].name;
- DCHECK(!container_to_codec_mask_map_.count(name));
- container_to_codec_mask_map_[name] = kContainerToCodecMasks[i].type;
- }
- for (size_t i = 0; i < arraysize(kCodecStrings); ++i) {
- const std::string& name = kCodecStrings[i].name;
- DCHECK(!codec_string_map_.count(name));
- codec_string_map_[name] = kCodecStrings[i].type;
- }
-
- UpdateSupportedKeySystems();
-
-#if defined(WIDEVINE_CDM_AVAILABLE)
- key_systems_support_uma_.AddKeySystemToReport(kWidevineKeySystem);
-#endif // defined(WIDEVINE_CDM_AVAILABLE)
-}
-
-EmeInitDataType KeySystems::GetInitDataTypeForName(
- const std::string& init_data_type) const {
- InitDataTypesMap::const_iterator iter =
- init_data_type_name_map_.find(init_data_type);
- if (iter != init_data_type_name_map_.end())
- return iter->second;
- return media::EME_INIT_DATA_TYPE_NONE;
-}
-
-SupportedCodecs KeySystems::GetCodecMaskForContainer(
- const std::string& container) const {
- ContainerCodecsMap::const_iterator iter =
- container_to_codec_mask_map_.find(container);
- if (iter != container_to_codec_mask_map_.end())
- return iter->second;
- return media::EME_CODEC_NONE;
-}
-
-EmeCodec KeySystems::GetCodecForString(const std::string& codec) const {
- CodecsMap::const_iterator iter = codec_string_map_.find(codec);
- if (iter != codec_string_map_.end())
- return iter->second;
- return media::EME_CODEC_NONE;
-}
-
-const std::string& KeySystems::GetConcreteKeySystemName(
- const std::string& key_system) const {
- ParentKeySystemMap::const_iterator iter =
- parent_key_system_map_.find(key_system);
- if (iter != parent_key_system_map_.end())
- return iter->second;
- return key_system;
-}
-
-void KeySystems::UpdateIfNeeded() {
-#if defined(WIDEVINE_CDM_AVAILABLE)
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!needs_update_)
- return;
-
- // The update could involve a sync IPC to the browser process. Use a minimum
- // update interval to avoid unnecessary frequent IPC to the browser.
- static const int kMinUpdateIntervalInSeconds = 1;
- base::Time now = base::Time::Now();
- if (now - last_update_time_ <
- base::TimeDelta::FromSeconds(kMinUpdateIntervalInSeconds)) {
- return;
- }
-
- UpdateSupportedKeySystems();
-#endif
-}
-
-void KeySystems::UpdateSupportedKeySystems() {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(needs_update_);
- concrete_key_system_map_.clear();
- parent_key_system_map_.clear();
-
- // Build KeySystemInfo.
- std::vector<KeySystemInfo> key_systems_info;
- GetContentClient()->renderer()->AddKeySystems(&key_systems_info);
- // Clear Key is always supported.
- AddClearKey(&key_systems_info);
-
- AddConcreteSupportedKeySystems(key_systems_info);
-
-#if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT)
- if (IsConcreteSupportedKeySystem(kWidevineKeySystem))
- needs_update_ = false;
-#endif
-
- last_update_time_ = base::Time::Now();
-}
-
-void KeySystems::AddConcreteSupportedKeySystems(
- const std::vector<KeySystemInfo>& concrete_key_systems) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(concrete_key_system_map_.empty());
- DCHECK(parent_key_system_map_.empty());
-
- for (size_t i = 0; i < concrete_key_systems.size(); ++i) {
- const KeySystemInfo& key_system_info = concrete_key_systems[i];
- AddConcreteSupportedKeySystem(key_system_info.key_system,
- key_system_info.use_aes_decryptor,
-#if defined(ENABLE_PEPPER_CDMS)
- key_system_info.pepper_type,
-#endif
- key_system_info.supported_init_data_types,
- key_system_info.supported_codecs,
- key_system_info.parent_key_system);
- }
-}
-
-void KeySystems::AddConcreteSupportedKeySystem(
- const std::string& concrete_key_system,
- bool use_aes_decryptor,
-#if defined(ENABLE_PEPPER_CDMS)
- const std::string& pepper_type,
-#endif
- SupportedInitDataTypes supported_init_data_types,
- SupportedCodecs supported_codecs,
- const std::string& parent_key_system) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!IsConcreteSupportedKeySystem(concrete_key_system))
- << "Key system '" << concrete_key_system << "' already registered";
- DCHECK(!parent_key_system_map_.count(concrete_key_system))
- << "'" << concrete_key_system << " is already registered as a parent";
-
- KeySystemProperties properties;
- properties.use_aes_decryptor = use_aes_decryptor;
-#if defined(ENABLE_PEPPER_CDMS)
- DCHECK_EQ(use_aes_decryptor, pepper_type.empty());
- properties.pepper_type = pepper_type;
-#endif
-
- properties.supported_init_data_types = supported_init_data_types;
- properties.supported_codecs = supported_codecs;
-
- concrete_key_system_map_[concrete_key_system] = properties;
-
- if (!parent_key_system.empty()) {
- DCHECK(!IsConcreteSupportedKeySystem(parent_key_system))
- << "Parent '" << parent_key_system << "' already registered concrete";
- DCHECK(!parent_key_system_map_.count(parent_key_system))
- << "Parent '" << parent_key_system << "' already registered";
- parent_key_system_map_[parent_key_system] = concrete_key_system;
- }
-}
-
-bool KeySystems::IsConcreteSupportedKeySystem(const std::string& key_system) {
- DCHECK(thread_checker_.CalledOnValidThread());
- return concrete_key_system_map_.count(key_system) != 0;
-}
-
-bool KeySystems::IsSupportedContainer(
- const std::string& container,
- SupportedCodecs key_system_supported_codecs) const {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!container.empty());
-
- // When checking container support for EME, "audio/foo" should be treated the
- // same as "video/foo". Convert the |container| to achieve this.
- // TODO(xhwang): Replace this with real checks against supported initDataTypes
- // combined with supported demuxers.
- std::string canonical_container = container;
- if (container.find("audio/") == 0)
- canonical_container.replace(0, 6, "video/");
-
- // A container is supported iif at least one codec in that container is
- // supported.
- SupportedCodecs supported_codecs =
- GetCodecMaskForContainer(canonical_container);
- return (supported_codecs & key_system_supported_codecs) != 0;
-}
-
-bool KeySystems::IsSupportedContainerAndCodecs(
- const std::string& container,
- const std::vector<std::string>& codecs,
- SupportedCodecs key_system_supported_codecs) const {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!container.empty());
- DCHECK(!codecs.empty());
- DCHECK(IsSupportedContainer(container, key_system_supported_codecs));
-
- SupportedCodecs container_supported_codecs =
- GetCodecMaskForContainer(container);
-
- for (size_t i = 0; i < codecs.size(); ++i) {
- // TODO(sandersd): This should fail for isTypeSupported().
- // http://crbug.com/417461
- if (codecs[i].empty())
- continue;
-
- EmeCodec codec = GetCodecForString(codecs[i]);
-
- // Unsupported codec.
- if (!(codec & key_system_supported_codecs))
- return false;
-
- // Unsupported codec/container combination, e.g. "video/webm" and "avc1".
- if (!(codec & container_supported_codecs))
- return false;
- }
-
- return true;
-}
-
-bool KeySystems::IsSupportedKeySystem(const std::string& key_system) {
- DCHECK(thread_checker_.CalledOnValidThread());
- return (concrete_key_system_map_.count(key_system) ||
- parent_key_system_map_.count(key_system));
-}
-
-bool KeySystems::IsSupportedKeySystemWithInitDataType(
- const std::string& key_system,
- const std::string& init_data_type) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // If |key_system| is a parent key system, use its concrete child.
- const std::string& concrete_key_system = GetConcreteKeySystemName(key_system);
-
- // Locate |concrete_key_system|.
- KeySystemPropertiesMap::const_iterator key_system_iter =
- concrete_key_system_map_.find(concrete_key_system);
- if (key_system_iter == concrete_key_system_map_.end())
- return false;
-
- // Check |init_data_type| and |key_system| x |init_data_type|.
- const KeySystemProperties& properties = key_system_iter->second;
- EmeInitDataType eme_init_data_type = GetInitDataTypeForName(init_data_type);
- return (properties.supported_init_data_types & eme_init_data_type) != 0;
-}
-
-// TODO(sandersd): Reorganize to be more similar to
-// IsKeySystemSupportedWithInitDataType(). Note that a fork may still be
-// required; http://crbug.com/417461.
-bool KeySystems::IsSupportedKeySystemWithMediaMimeType(
- const std::string& mime_type,
- const std::vector<std::string>& codecs,
- const std::string& key_system) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // If |key_system| is a parent key system, use its concrete child.
- const std::string& concrete_key_system = GetConcreteKeySystemName(key_system);
-
- bool has_type = !mime_type.empty();
-
- key_systems_support_uma_.ReportKeySystemQuery(key_system, has_type);
-
- // Check key system support.
- KeySystemPropertiesMap::const_iterator key_system_iter =
- concrete_key_system_map_.find(concrete_key_system);
- if (key_system_iter == concrete_key_system_map_.end())
- return false;
-
- key_systems_support_uma_.ReportKeySystemSupport(key_system, false);
-
- if (!has_type) {
- DCHECK(codecs.empty());
- return true;
- }
-
- SupportedCodecs key_system_supported_codecs =
- key_system_iter->second.supported_codecs;
-
- if (!IsSupportedContainer(mime_type, key_system_supported_codecs))
- return false;
-
- if (!codecs.empty() &&
- !IsSupportedContainerAndCodecs(
- mime_type, codecs, key_system_supported_codecs)) {
- return false;
- }
-
- key_systems_support_uma_.ReportKeySystemSupport(key_system, true);
- return true;
-}
-
-bool KeySystems::UseAesDecryptor(const std::string& concrete_key_system) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- KeySystemPropertiesMap::const_iterator key_system_iter =
- concrete_key_system_map_.find(concrete_key_system);
- if (key_system_iter == concrete_key_system_map_.end()) {
- DLOG(FATAL) << concrete_key_system << " is not a known concrete system";
- return false;
- }
-
- return key_system_iter->second.use_aes_decryptor;
-}
-
-#if defined(ENABLE_PEPPER_CDMS)
-std::string KeySystems::GetPepperType(const std::string& concrete_key_system) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- KeySystemPropertiesMap::const_iterator key_system_iter =
- concrete_key_system_map_.find(concrete_key_system);
- if (key_system_iter == concrete_key_system_map_.end()) {
- DLOG(FATAL) << concrete_key_system << " is not a known concrete system";
- return std::string();
- }
-
- const std::string& type = key_system_iter->second.pepper_type;
- DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based";
- return type;
-}
-#endif
-
-void KeySystems::AddContainerMask(const std::string& container, uint32 mask) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!container_to_codec_mask_map_.count(container));
- container_to_codec_mask_map_[container] = static_cast<EmeCodec>(mask);
-}
-
-void KeySystems::AddCodecMask(const std::string& codec, uint32 mask) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(!codec_string_map_.count(codec));
- codec_string_map_[codec] = static_cast<EmeCodec>(mask);
-}
-
-//------------------------------------------------------------------------------
-
-std::string GetUnprefixedKeySystemName(const std::string& key_system) {
- if (key_system == kClearKeyKeySystem)
- return kUnsupportedClearKeyKeySystem;
-
- if (key_system == kPrefixedClearKeyKeySystem)
- return kClearKeyKeySystem;
-
- return key_system;
-}
-
-std::string GetPrefixedKeySystemName(const std::string& key_system) {
- DCHECK_NE(key_system, kPrefixedClearKeyKeySystem);
-
- if (key_system == kClearKeyKeySystem)
- return kPrefixedClearKeyKeySystem;
-
- return key_system;
-}
-
-bool IsSaneInitDataTypeWithContainer(
- const std::string& init_data_type,
- const std::string& container) {
- if (init_data_type == "cenc") {
- return container == "audio/mp4" || container == "video/mp4";
- } else if (init_data_type == "webm") {
- return container == "audio/webm" || container == "video/webm";
- } else {
- return true;
- }
-}
-
-bool IsConcreteSupportedKeySystem(const std::string& key_system) {
- return KeySystems::GetInstance().IsConcreteSupportedKeySystem(key_system);
-}
-
-bool IsSupportedKeySystem(const std::string& key_system) {
- return KeySystems::GetInstance().IsSupportedKeySystem(key_system);
-}
-
-bool IsSupportedKeySystemWithInitDataType(
- const std::string& key_system,
- const std::string& init_data_type) {
- return KeySystems::GetInstance().IsSupportedKeySystemWithInitDataType(
- key_system, init_data_type);
-}
-
-bool IsSupportedKeySystemWithMediaMimeType(
- const std::string& mime_type,
- const std::vector<std::string>& codecs,
- const std::string& key_system) {
- return KeySystems::GetInstance().IsSupportedKeySystemWithMediaMimeType(
- mime_type, codecs, key_system);
-}
-
-std::string KeySystemNameForUMA(const std::string& key_system) {
- if (key_system == kClearKeyKeySystem)
- return "ClearKey";
-#if defined(WIDEVINE_CDM_AVAILABLE)
- if (key_system == kWidevineKeySystem)
- return "Widevine";
-#endif // WIDEVINE_CDM_AVAILABLE
- return "Unknown";
-}
-
-bool CanUseAesDecryptor(const std::string& concrete_key_system) {
- return KeySystems::GetInstance().UseAesDecryptor(concrete_key_system);
-}
-
-#if defined(ENABLE_PEPPER_CDMS)
-std::string GetPepperType(const std::string& concrete_key_system) {
- return KeySystems::GetInstance().GetPepperType(concrete_key_system);
-}
-#endif
-
-// These two functions are for testing purpose only. The declaration in the
-// header file is guarded by "#if defined(UNIT_TEST)" so that they can be used
-// by tests but not non-test code. However, this .cc file is compiled as part of
-// "content" where "UNIT_TEST" is not defined. So we need to specify
-// "CONTENT_EXPORT" here again so that they are visible to tests.
-
-CONTENT_EXPORT void AddContainerMask(const std::string& container,
- uint32 mask) {
- KeySystems::GetInstance().AddContainerMask(container, mask);
-}
-
-CONTENT_EXPORT void AddCodecMask(const std::string& codec, uint32 mask) {
- KeySystems::GetInstance().AddCodecMask(codec, mask);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/crypto/key_systems.h b/chromium/content/renderer/media/crypto/key_systems.h
deleted file mode 100644
index 03d40024579..00000000000
--- a/chromium/content/renderer/media/crypto/key_systems.h
+++ /dev/null
@@ -1,80 +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_KEY_SYSTEMS_H_
-#define CONTENT_RENDERER_MEDIA_CRYPTO_KEY_SYSTEMS_H_
-
-#include <string>
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// Prefixed EME API only supports prefixed (webkit-) key system name for
-// certain key systems. But internally only unprefixed key systems are
-// supported. The following two functions help convert between prefixed and
-// unprefixed key system names.
-
-// Gets the unprefixed key system name for |key_system|.
-std::string GetUnprefixedKeySystemName(const std::string& key_system);
-
-// Gets the prefixed key system name for |key_system|.
-std::string GetPrefixedKeySystemName(const std::string& key_system);
-
-// Returns false if a container-specific |init_data_type| is specified with an
-// inappropriate container.
-// TODO(sandersd): Remove this essentially internal detail if the spec is
-// updated to not convolve the two in a single method call.
-// TODO(sandersd): Use enum values instead of strings. http://crbug.com/417440
-bool IsSaneInitDataTypeWithContainer(
- const std::string& init_data_type,
- const std::string& container);
-
-// Note: Shouldn't be used for prefixed API as the original
-// IsSupportedKeySystemWithMediaMimeType() path reports UMAs, but this path does
-// not.
-bool IsSupportedKeySystem(const std::string& key_system);
-
-bool IsSupportedKeySystemWithInitDataType(
- const std::string& key_system,
- const std::string& init_data_type);
-
-// Returns whether |key_system| is a real supported key system that can be
-// instantiated.
-// Abstract parent |key_system| strings will return false.
-// Call IsSupportedKeySystemWithMediaMimeType() to determine whether a
-// |key_system| supports a specific type of media or to check parent key
-// systems.
-CONTENT_EXPORT bool IsConcreteSupportedKeySystem(const std::string& key_system);
-
-// Returns whether |key_sytem| supports the specified media type and codec(s).
-CONTENT_EXPORT bool IsSupportedKeySystemWithMediaMimeType(
- const std::string& mime_type,
- const std::vector<std::string>& codecs,
- const std::string& key_system);
-
-// Returns a name for |key_system| suitable to UMA logging.
-CONTENT_EXPORT std::string KeySystemNameForUMA(const std::string& key_system);
-
-// Returns whether AesDecryptor can be used for the given |concrete_key_system|.
-CONTENT_EXPORT bool CanUseAesDecryptor(const std::string& concrete_key_system);
-
-#if defined(ENABLE_PEPPER_CDMS)
-// Returns the Pepper MIME type for |concrete_key_system|.
-// Returns empty string if |concrete_key_system| is unknown or not Pepper-based.
-CONTENT_EXPORT std::string GetPepperType(
- const std::string& concrete_key_system);
-#endif
-
-#if defined(UNIT_TEST)
-// Helper functions to add container/codec types for testing purposes.
-CONTENT_EXPORT void AddContainerMask(const std::string& container, uint32 mask);
-CONTENT_EXPORT void AddCodecMask(const std::string& codec, uint32 mask);
-#endif // defined(UNIT_TEST)
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_CRYPTO_KEY_SYSTEMS_H_
diff --git a/chromium/content/renderer/media/crypto/key_systems_support_uma.cc b/chromium/content/renderer/media/crypto/key_systems_support_uma.cc
deleted file mode 100644
index bd90aeb8bc9..00000000000
--- a/chromium/content/renderer/media/crypto/key_systems_support_uma.cc
+++ /dev/null
@@ -1,136 +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/key_systems_support_uma.h"
-
-#include <string>
-
-#include "base/metrics/histogram.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/renderer/media/crypto/key_systems.h"
-
-namespace content {
-
-namespace {
-
-const char kKeySystemSupportUMAPrefix[] = "Media.EME.KeySystemSupport.";
-
-// These values are reported to UMA. Do not change the existing values!
-enum KeySystemSupportStatus {
- KEY_SYSTEM_QUERIED = 0,
- KEY_SYSTEM_SUPPORTED = 1,
- KEY_SYSTEM_WITH_TYPE_QUERIED = 2,
- KEY_SYSTEM_WITH_TYPE_SUPPORTED = 3,
- KEY_SYSTEM_SUPPORT_STATUS_COUNT
-};
-
-// Reports an event only once.
-class OneTimeReporter {
- public:
- OneTimeReporter(const std::string& key_system, KeySystemSupportStatus status);
- ~OneTimeReporter();
-
- void Report();
-
- private:
- bool is_reported_;
- const std::string key_system_;
- const KeySystemSupportStatus status_;
-};
-
-OneTimeReporter::OneTimeReporter(const std::string& key_system,
- KeySystemSupportStatus status)
- : is_reported_(false), key_system_(key_system), status_(status) {
-}
-
-OneTimeReporter::~OneTimeReporter() {}
-
-void OneTimeReporter::Report() {
- if (is_reported_)
- return;
-
- // Not using UMA_HISTOGRAM_ENUMERATION directly because UMA_* macros require
- // the names to be constant throughout the process' lifetime.
- base::LinearHistogram::FactoryGet(
- kKeySystemSupportUMAPrefix + KeySystemNameForUMA(key_system_), 1,
- KEY_SYSTEM_SUPPORT_STATUS_COUNT, KEY_SYSTEM_SUPPORT_STATUS_COUNT + 1,
- base::Histogram::kUmaTargetedHistogramFlag)->Add(status_);
-
- is_reported_ = true;
-}
-
-} // namespace
-
-class KeySystemsSupportUMA::Reporter {
- public:
- explicit Reporter(const std::string& key_system);
- ~Reporter();
-
- void Report(bool has_type, bool is_supported);
-
- private:
- const std::string key_system_;
-
- OneTimeReporter call_reporter_;
- OneTimeReporter call_with_type_reporter_;
- OneTimeReporter support_reporter_;
- OneTimeReporter support_with_type_reporter_;
-};
-
-KeySystemsSupportUMA::Reporter::Reporter(const std::string& key_system)
- : key_system_(key_system),
- call_reporter_(key_system, KEY_SYSTEM_QUERIED),
- call_with_type_reporter_(key_system, KEY_SYSTEM_WITH_TYPE_QUERIED),
- support_reporter_(key_system, KEY_SYSTEM_SUPPORTED),
- support_with_type_reporter_(key_system, KEY_SYSTEM_WITH_TYPE_SUPPORTED) {}
-
-KeySystemsSupportUMA::Reporter::~Reporter() {}
-
-void KeySystemsSupportUMA::Reporter::Report(bool has_type, bool is_supported) {
- call_reporter_.Report();
- if (has_type)
- call_with_type_reporter_.Report();
-
- if (!is_supported)
- return;
-
- support_reporter_.Report();
- if (has_type)
- support_with_type_reporter_.Report();
-}
-
-KeySystemsSupportUMA::KeySystemsSupportUMA() {}
-
-KeySystemsSupportUMA::~KeySystemsSupportUMA() {}
-
-void KeySystemsSupportUMA::AddKeySystemToReport(const std::string& key_system) {
- DCHECK(!GetReporter(key_system));
- reporters_.set(key_system, scoped_ptr<Reporter>(new Reporter(key_system)));
-}
-
-void KeySystemsSupportUMA::ReportKeySystemQuery(const std::string& key_system,
- bool has_type) {
- Reporter* reporter = GetReporter(key_system);
- if (!reporter)
- return;
- reporter->Report(has_type, false);
-}
-
-void KeySystemsSupportUMA::ReportKeySystemSupport(const std::string& key_system,
- bool has_type) {
- Reporter* reporter = GetReporter(key_system);
- if (!reporter)
- return;
- reporter->Report(has_type, true);
-}
-
-KeySystemsSupportUMA::Reporter* KeySystemsSupportUMA::GetReporter(
- const std::string& key_system) {
- Reporters::iterator reporter = reporters_.find(key_system);
- if (reporter == reporters_.end())
- return NULL;
- return reporter->second;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/crypto/key_systems_support_uma.h b/chromium/content/renderer/media/crypto/key_systems_support_uma.h
deleted file mode 100644
index 95e1b02bcd4..00000000000
--- a/chromium/content/renderer/media/crypto/key_systems_support_uma.h
+++ /dev/null
@@ -1,57 +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_KEY_SYSTEMS_SUPPORT_UMA_H_
-#define CONTENT_RENDERER_MEDIA_CRYPTO_KEY_SYSTEMS_SUPPORT_UMA_H_
-
-#include <string>
-
-#include "base/containers/scoped_ptr_hash_map.h"
-
-namespace content {
-
-// Key system support UMA statistics for queried key systems.
-// 1. The key system is queried (with or without a MIME type).
-// 2. The key system is queried with a MIME type.
-// 3. The queried key system is supported (with or without a MIME type). This is
-// reported when the key system is supported when queried, regardless of
-// whether a MIME type is specified.
-// 4. The queried key system is supported with a MIME type. This is reported
-// when the key system is supported when queried without a MIME type
-// specified.
-// Note: All 4 stats are only reported once per renderer process per key system.
-class KeySystemsSupportUMA {
- public:
- KeySystemsSupportUMA();
- ~KeySystemsSupportUMA();
-
- // Adds a |key_system| for which query/support statistics are reported.
- // If you use this function to add key system to report, make sure to update
- // AddKeySystemSupportActions() in tools/metrics/actions/extract_actions.py.
- void AddKeySystemToReport(const std::string& key_system);
-
- // Reports that the |key_system| is queried. When |has_type|, also reports
- // that the |key_system| with a MIME type is queried.
- void ReportKeySystemQuery(const std::string& key_system, bool has_type);
-
- // Reports that the queried |key_system| is supported. When |has_type| (a
- // a MIME type is specified in the query), also reports that the queried
- // |key_system| is supported with that MIME type.
- void ReportKeySystemSupport(const std::string& key_system, bool has_type);
-
- private:
- class Reporter;
-
- // Returns the Reporter for |key_system|. Returns NULL if |key_system| was not
- // added for UMA reporting.
- Reporter* GetReporter(const std::string& key_system);
-
- // Key system <-> Reporter map.
- typedef base::ScopedPtrHashMap<std::string, Reporter> Reporters;
- Reporters reporters_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_CRYPTO_KEY_SYSTEMS_SUPPORT_UMA_H_
diff --git a/chromium/content/renderer/media/crypto/key_systems_unittest.cc b/chromium/content/renderer/media/crypto/key_systems_unittest.cc
deleted file mode 100644
index d7c980dd17f..00000000000
--- a/chromium/content/renderer/media/crypto/key_systems_unittest.cc
+++ /dev/null
@@ -1,649 +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 <string>
-#include <vector>
-
-#include "content/public/common/content_client.h"
-#include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/media/crypto/key_systems.h"
-#include "content/test/test_content_client.h"
-#include "media/base/eme_constants.h"
-#include "media/base/key_system_info.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebString.h"
-
-#include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR.
-
-// Death tests are not always available, including on Android.
-// EXPECT_DEBUG_DEATH_PORTABLE executes tests correctly except in the case that
-// death tests are not available and NDEBUG is not defined.
-#if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
-#define EXPECT_DEBUG_DEATH_PORTABLE(statement, regex) \
- EXPECT_DEBUG_DEATH(statement, regex)
-#else
-#if defined(NDEBUG)
-#define EXPECT_DEBUG_DEATH_PORTABLE(statement, regex) \
- do { statement; } while (false)
-#else
-#include "base/logging.h"
-#define EXPECT_DEBUG_DEATH_PORTABLE(statement, regex) \
- LOG(WARNING) << "Death tests are not supported on this platform.\n" \
- << "Statement '" #statement "' cannot be verified.";
-#endif // defined(NDEBUG)
-#endif // defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
-
-namespace content {
-
-using blink::WebString;
-using media::KeySystemInfo;
-
-// These are the (fake) key systems that are registered for these tests.
-// kUsesAes uses the AesDecryptor like Clear Key.
-// kExternal uses an external CDM, such as Pepper-based or Android platform CDM.
-const char kUsesAes[] = "org.example.clear";
-const char kUsesAesParent[] = "org.example"; // Not registered.
-const char kExternal[] = "com.example.test";
-const char kExternalParent[] = "com.example";
-
-const char kClearKey[] = "org.w3.clearkey";
-const char kPrefixedClearKey[] = "webkit-org.w3.clearkey";
-const char kExternalClearKey[] = "org.chromium.externalclearkey";
-
-const char kAudioWebM[] = "audio/webm";
-const char kVideoWebM[] = "video/webm";
-const char kAudioFoo[] = "audio/foo";
-const char kVideoFoo[] = "video/foo";
-
-// Pick some arbitrary bit fields as long as they are not in conflict with the
-// real ones.
-enum TestCodec {
- TEST_CODEC_FOO_AUDIO = 1 << 10, // An audio codec for foo container.
- TEST_CODEC_FOO_AUDIO_ALL = TEST_CODEC_FOO_AUDIO,
- TEST_CODEC_FOO_VIDEO = 1 << 11, // A video codec for foo container.
- TEST_CODEC_FOO_VIDEO_ALL = TEST_CODEC_FOO_VIDEO,
- TEST_CODEC_FOO_ALL = TEST_CODEC_FOO_AUDIO_ALL | TEST_CODEC_FOO_VIDEO_ALL
-};
-
-COMPILE_ASSERT((TEST_CODEC_FOO_ALL & media::EME_CODEC_ALL) ==
- media::EME_CODEC_NONE,
- test_codec_masks_should_only_use_invalid_codec_masks);
-
-// Adds test container and codec masks.
-// This function must be called after SetContentClient() is called.
-// More details: AddXxxMask() will create KeySystems if it hasn't been created.
-// During KeySystems's construction GetContentClient() will be used to add key
-// systems. In test code, the content client is set by SetContentClient().
-// Therefore, SetContentClient() must be called before this function to avoid
-// access violation.
-static void AddContainerAndCodecMasksForTest() {
- // Since KeySystems is a singleton. Make sure we only add test container and
- // codec masks once per process.
- static bool is_test_masks_added = false;
-
- if (is_test_masks_added)
- return;
-
- AddContainerMask("audio/foo", TEST_CODEC_FOO_AUDIO_ALL);
- AddContainerMask("video/foo", TEST_CODEC_FOO_ALL);
- AddCodecMask("fooaudio", TEST_CODEC_FOO_AUDIO);
- AddCodecMask("foovideo", TEST_CODEC_FOO_VIDEO);
-
- is_test_masks_added = true;
-}
-
-class TestContentRendererClient : public ContentRendererClient {
- void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override;
-};
-
-void TestContentRendererClient::AddKeySystems(
- std::vector<media::KeySystemInfo>* key_systems) {
- KeySystemInfo aes(kUsesAes);
- aes.supported_codecs = media::EME_CODEC_WEBM_ALL;
- aes.supported_codecs |= TEST_CODEC_FOO_ALL;
- aes.supported_init_data_types = media::EME_INIT_DATA_TYPE_WEBM;
- aes.use_aes_decryptor = true;
- key_systems->push_back(aes);
-
- KeySystemInfo ext(kExternal);
- ext.supported_codecs = media::EME_CODEC_WEBM_ALL;
- ext.supported_codecs |= TEST_CODEC_FOO_ALL;
- ext.supported_init_data_types = media::EME_INIT_DATA_TYPE_WEBM;
- ext.parent_key_system = kExternalParent;
-#if defined(ENABLE_PEPPER_CDMS)
- ext.pepper_type = "application/x-ppapi-external-cdm";
-#endif // defined(ENABLE_PEPPER_CDMS)
- key_systems->push_back(ext);
-}
-
-// TODO(sandersd): Refactor. http://crbug.com/417444
-class KeySystemsTest : public testing::Test {
- protected:
- KeySystemsTest() {
- vp8_codec_.push_back("vp8");
-
- vp80_codec_.push_back("vp8.0");
-
- vp9_codec_.push_back("vp9");
-
- vp90_codec_.push_back("vp9.0");
-
- vorbis_codec_.push_back("vorbis");
-
- vp8_and_vorbis_codecs_.push_back("vp8");
- vp8_and_vorbis_codecs_.push_back("vorbis");
-
- vp9_and_vorbis_codecs_.push_back("vp9");
- vp9_and_vorbis_codecs_.push_back("vorbis");
-
- foovideo_codec_.push_back("foovideo");
-
- foovideo_extended_codec_.push_back("foovideo.4D400C");
-
- foovideo_dot_codec_.push_back("foovideo.");
-
- fooaudio_codec_.push_back("fooaudio");
-
- foovideo_and_fooaudio_codecs_.push_back("foovideo");
- foovideo_and_fooaudio_codecs_.push_back("fooaudio");
-
- unknown_codec_.push_back("unknown");
-
- mixed_codecs_.push_back("vorbis");
- mixed_codecs_.push_back("foovideo");
-
- // KeySystems requires a valid ContentRendererClient and thus ContentClient.
- // The TestContentClient is not available inside Death Tests on some
- // platforms (see below). Therefore, always provide a TestContentClient.
- // Explanation: When Death Tests fork, there is a valid ContentClient.
- // However, when they launch a new process instead of forking, the global
- // variable is not copied and for some reason TestContentClientInitializer
- // does not get created to set the global variable in the new process.
- SetContentClient(&test_content_client_);
- SetRendererClientForTesting(&content_renderer_client_);
- }
-
- void SetUp() override { AddContainerAndCodecMasksForTest(); }
-
- ~KeySystemsTest() override {
- // Clear the use of content_client_, which was set in SetUp().
- SetContentClient(NULL);
- }
-
- typedef std::vector<std::string> CodecVector;
-
- const CodecVector& no_codecs() const { return no_codecs_; }
-
- const CodecVector& vp8_codec() const { return vp8_codec_; }
- const CodecVector& vp80_codec() const { return vp80_codec_; }
- const CodecVector& vp9_codec() const { return vp9_codec_; }
- const CodecVector& vp90_codec() const { return vp90_codec_; }
-
- const CodecVector& vorbis_codec() const { return vorbis_codec_; }
-
- const CodecVector& vp8_and_vorbis_codecs() const {
- return vp8_and_vorbis_codecs_;
- }
- const CodecVector& vp9_and_vorbis_codecs() const {
- return vp9_and_vorbis_codecs_;
- }
-
- const CodecVector& foovideo_codec() const { return foovideo_codec_; }
- const CodecVector& foovideo_extended_codec() const {
- return foovideo_extended_codec_;
- }
- const CodecVector& foovideo_dot_codec() const { return foovideo_dot_codec_; }
- const CodecVector& fooaudio_codec() const { return fooaudio_codec_; }
- const CodecVector& foovideo_and_fooaudio_codecs() const {
- return foovideo_and_fooaudio_codecs_;
- }
-
- const CodecVector& unknown_codec() const { return unknown_codec_; }
-
- const CodecVector& mixed_codecs() const { return mixed_codecs_; }
-
- private:
- const CodecVector no_codecs_;
- CodecVector vp8_codec_;
- CodecVector vp80_codec_;
- CodecVector vp9_codec_;
- CodecVector vp90_codec_;
- CodecVector vorbis_codec_;
- CodecVector vp8_and_vorbis_codecs_;
- CodecVector vp9_and_vorbis_codecs_;
-
- CodecVector foovideo_codec_;
- CodecVector foovideo_extended_codec_;
- CodecVector foovideo_dot_codec_;
- CodecVector fooaudio_codec_;
- CodecVector foovideo_and_fooaudio_codecs_;
-
- CodecVector unknown_codec_;
-
- CodecVector mixed_codecs_;
-
- TestContentClient test_content_client_;
- TestContentRendererClient content_renderer_client_;
-};
-
-// TODO(ddorwin): Consider moving GetPepperType() calls out to their own test.
-
-TEST_F(KeySystemsTest, EmptyKeySystem) {
- EXPECT_FALSE(IsConcreteSupportedKeySystem(std::string()));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), std::string()));
- EXPECT_EQ("Unknown", KeySystemNameForUMA(std::string()));
-}
-
-// Clear Key is the only key system registered in content.
-TEST_F(KeySystemsTest, ClearKey) {
- EXPECT_TRUE(IsConcreteSupportedKeySystem(kClearKey));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kClearKey));
-
- EXPECT_EQ("ClearKey", KeySystemNameForUMA(kClearKey));
-
- // Prefixed Clear Key is not supported internally.
- EXPECT_FALSE(IsConcreteSupportedKeySystem(kPrefixedClearKey));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kPrefixedClearKey));
- EXPECT_EQ("Unknown", KeySystemNameForUMA(kPrefixedClearKey));
-}
-
-// The key system is not registered and therefore is unrecognized.
-TEST_F(KeySystemsTest, Basic_UnrecognizedKeySystem) {
- static const char* const kUnrecognized = "org.example.unrecognized";
-
- EXPECT_FALSE(IsConcreteSupportedKeySystem(kUnrecognized));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kUnrecognized));
-
- EXPECT_EQ("Unknown", KeySystemNameForUMA(kUnrecognized));
-
- bool can_use = false;
- EXPECT_DEBUG_DEATH_PORTABLE(
- can_use = CanUseAesDecryptor(kUnrecognized),
- "org.example.unrecognized is not a known concrete system");
- EXPECT_FALSE(can_use);
-
-#if defined(ENABLE_PEPPER_CDMS)
- std::string type;
- EXPECT_DEBUG_DEATH(type = GetPepperType(kUnrecognized),
- "org.example.unrecognized is not a known concrete system");
- EXPECT_TRUE(type.empty());
-#endif
-}
-
-TEST_F(KeySystemsTest, Basic_UsesAesDecryptor) {
- EXPECT_TRUE(IsConcreteSupportedKeySystem(kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kUsesAes));
-
- // No UMA value for this test key system.
- EXPECT_EQ("Unknown", KeySystemNameForUMA(kUsesAes));
-
- EXPECT_TRUE(CanUseAesDecryptor(kUsesAes));
-#if defined(ENABLE_PEPPER_CDMS)
- std::string type;
- EXPECT_DEBUG_DEATH(type = GetPepperType(kUsesAes),
- "org.example.clear is not Pepper-based");
- EXPECT_TRUE(type.empty());
-#endif
-}
-
-TEST_F(KeySystemsTest,
- IsSupportedKeySystemWithMediaMimeType_UsesAesDecryptor_TypesContainer1) {
- // Valid video types.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp8_codec(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp80_codec(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp8_and_vorbis_codecs(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp9_codec(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp90_codec(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp9_and_vorbis_codecs(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vorbis_codec(), kUsesAes));
-
- // Non-Webm codecs.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, foovideo_codec(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, unknown_codec(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, mixed_codecs(), kUsesAes));
-
- // Valid audio types.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, no_codecs(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vorbis_codec(), kUsesAes));
-
- // Non-audio codecs.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vp8_codec(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vp8_and_vorbis_codecs(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vp9_codec(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vp9_and_vorbis_codecs(), kUsesAes));
-
- // Non-Webm codec.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, fooaudio_codec(), kUsesAes));
-}
-
-// No parent is registered for UsesAes.
-TEST_F(KeySystemsTest, Parent_NoParentRegistered) {
- EXPECT_FALSE(IsConcreteSupportedKeySystem(kUsesAesParent));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kUsesAesParent));
-
- // The parent is not supported for most things.
- EXPECT_EQ("Unknown", KeySystemNameForUMA(kUsesAesParent));
- bool result = false;
- EXPECT_DEBUG_DEATH_PORTABLE(result = CanUseAesDecryptor(kUsesAesParent),
- "org.example is not a known concrete system");
- EXPECT_FALSE(result);
-#if defined(ENABLE_PEPPER_CDMS)
- std::string type;
- EXPECT_DEBUG_DEATH(type = GetPepperType(kUsesAesParent),
- "org.example is not a known concrete system");
- EXPECT_TRUE(type.empty());
-#endif
-}
-
-TEST_F(KeySystemsTest, IsSupportedKeySystem_InvalidVariants) {
- // Case sensitive.
- EXPECT_FALSE(IsConcreteSupportedKeySystem("org.example.ClEaR"));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), "org.example.ClEaR"));
-
- // TLDs are not allowed.
- EXPECT_FALSE(IsConcreteSupportedKeySystem("org."));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), "org."));
- EXPECT_FALSE(IsConcreteSupportedKeySystem("com"));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), "com"));
-
- // Extra period.
- EXPECT_FALSE(IsConcreteSupportedKeySystem("org.example."));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), "org.example."));
-
- // Incomplete.
- EXPECT_FALSE(IsConcreteSupportedKeySystem("org.example.clea"));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), "org.example.clea"));
-
- // Extra character.
- EXPECT_FALSE(IsConcreteSupportedKeySystem("org.example.clearz"));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), "org.example.clearz"));
-
- // There are no child key systems for UsesAes.
- EXPECT_FALSE(IsConcreteSupportedKeySystem("org.example.clear.foo"));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), "org.example.clear.foo"));
-}
-
-TEST_F(KeySystemsTest, IsSupportedKeySystemWithMediaMimeType_NoType) {
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- std::string(), no_codecs(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- std::string(), no_codecs(), kUsesAesParent));
-
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- std::string(), no_codecs(), "org.example.foo"));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- std::string(), no_codecs(), "org.example.clear.foo"));
-}
-
-// Tests the second registered container type.
-// TODO(ddorwin): Combined with TypesContainer1 in a future CL.
-TEST_F(KeySystemsTest,
- IsSupportedKeySystemWithMediaMimeType_UsesAesDecryptor_TypesContainer2) {
- // Valid video types.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, no_codecs(), kUsesAes));
- // The parent should be supported but is not. See http://crbug.com/164303.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, no_codecs(), kUsesAesParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_codec(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_and_fooaudio_codecs(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, fooaudio_codec(), kUsesAes));
-
- // Extended codecs fail because this is handled by SimpleWebMimeRegistryImpl.
- // They should really pass canPlayType().
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_extended_codec(), kUsesAes));
-
- // Invalid codec format.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_dot_codec(), kUsesAes));
-
- // Non-container2 codec.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, vp8_codec(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, unknown_codec(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, mixed_codecs(), kUsesAes));
-
- // Valid audio types.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, no_codecs(), kUsesAes));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, fooaudio_codec(), kUsesAes));
-
- // Non-audio codecs.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, foovideo_codec(), kUsesAes));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, foovideo_and_fooaudio_codecs(), kUsesAes));
-
- // Non-container2 codec.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, vorbis_codec(), kUsesAes));
-}
-
-//
-// Non-AesDecryptor-based key system.
-//
-
-TEST_F(KeySystemsTest, Basic_ExternalDecryptor) {
- EXPECT_TRUE(IsConcreteSupportedKeySystem(kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kExternal));
-
- EXPECT_FALSE(CanUseAesDecryptor(kExternal));
-#if defined(ENABLE_PEPPER_CDMS)
- EXPECT_EQ("application/x-ppapi-external-cdm", GetPepperType(kExternal));
-#endif // defined(ENABLE_PEPPER_CDMS)
-
-}
-
-TEST_F(KeySystemsTest, Parent_ParentRegistered) {
- // The parent system is not a concrete system but is supported.
- EXPECT_FALSE(IsConcreteSupportedKeySystem(kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kExternalParent));
-
- // The parent is not supported for most things.
- EXPECT_EQ("Unknown", KeySystemNameForUMA(kExternalParent));
- bool result = false;
- EXPECT_DEBUG_DEATH_PORTABLE(result = CanUseAesDecryptor(kExternalParent),
- "com.example is not a known concrete system");
- EXPECT_FALSE(result);
-#if defined(ENABLE_PEPPER_CDMS)
- std::string type;
- EXPECT_DEBUG_DEATH(type = GetPepperType(kExternalParent),
- "com.example is not a known concrete system");
- EXPECT_TRUE(type.empty());
-#endif
-}
-
-TEST_F(
- KeySystemsTest,
- IsSupportedKeySystemWithMediaMimeType_ExternalDecryptor_TypesContainer1) {
- // Valid video types.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp8_codec(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp80_codec(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp8_and_vorbis_codecs(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp9_codec(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp90_codec(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp9_and_vorbis_codecs(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vorbis_codec(), kExternal));
-
- // Valid video types - parent key system.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, no_codecs(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp8_codec(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp80_codec(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp8_and_vorbis_codecs(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp9_codec(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp90_codec(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vp9_and_vorbis_codecs(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, vorbis_codec(), kExternalParent));
-
- // Non-Webm codecs.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, foovideo_codec(), kExternal));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, unknown_codec(), kExternal));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoWebM, mixed_codecs(), kExternal));
-
- // Valid audio types.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, no_codecs(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vorbis_codec(), kExternal));
-
- // Valid audio types - parent key system.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, no_codecs(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vorbis_codec(), kExternalParent));
-
- // Non-audio codecs.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vp8_codec(), kExternal));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vp8_and_vorbis_codecs(), kExternal));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vp9_codec(), kExternal));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, vp9_and_vorbis_codecs(), kExternal));
-
- // Non-Webm codec.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioWebM, fooaudio_codec(), kExternal));
-}
-
-TEST_F(
- KeySystemsTest,
- IsSupportedKeySystemWithMediaMimeType_ExternalDecryptor_TypesContainer2) {
- // Valid video types.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, no_codecs(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_codec(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_and_fooaudio_codecs(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, fooaudio_codec(), kExternal));
-
- // Valid video types - parent key system.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, no_codecs(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_codec(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_and_fooaudio_codecs(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, fooaudio_codec(), kExternalParent));
-
- // Extended codecs fail because this is handled by SimpleWebMimeRegistryImpl.
- // They should really pass canPlayType().
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_extended_codec(), kExternal));
-
- // Invalid codec format.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, foovideo_dot_codec(), kExternal));
-
- // Non-container2 codecs.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, vp8_codec(), kExternal));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, unknown_codec(), kExternal));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kVideoFoo, mixed_codecs(), kExternal));
-
- // Valid audio types.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, no_codecs(), kExternal));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, fooaudio_codec(), kExternal));
-
- // Valid audio types - parent key system.
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, no_codecs(), kExternalParent));
- EXPECT_TRUE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, fooaudio_codec(), kExternalParent));
-
- // Non-audio codecs.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, foovideo_codec(), kExternal));
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, foovideo_and_fooaudio_codecs(), kExternal));
-
- // Non-container2 codec.
- EXPECT_FALSE(IsSupportedKeySystemWithMediaMimeType(
- kAudioFoo, vorbis_codec(), kExternal));
-}
-
-TEST_F(KeySystemsTest, KeySystemNameForUMA) {
- EXPECT_EQ("ClearKey", KeySystemNameForUMA(kClearKey));
- // Prefixed is not supported internally.
- EXPECT_EQ("Unknown", KeySystemNameForUMA(kPrefixedClearKey));
-
- // External Clear Key never has a UMA name.
- EXPECT_EQ("Unknown", KeySystemNameForUMA(kExternalClearKey));
-
-#if defined(WIDEVINE_CDM_AVAILABLE)
- const char* const kTestWidevineUmaName = "Widevine";
-#else
- const char* const kTestWidevineUmaName = "Unknown";
-#endif
- EXPECT_EQ(kTestWidevineUmaName, KeySystemNameForUMA("com.widevine.alpha"));
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/crypto/ppapi_decryptor.cc b/chromium/content/renderer/media/crypto/ppapi_decryptor.cc
index 1af098c1fbe..b828de51d09 100644
--- a/chromium/content/renderer/media/crypto/ppapi_decryptor.cc
+++ b/chromium/content/renderer/media/crypto/ppapi_decryptor.cc
@@ -10,92 +10,103 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
-#include "content/renderer/media/crypto/key_systems.h"
+#include "content/renderer/media/crypto/cdm_initialized_promise.h"
#include "content/renderer/pepper/content_decryptor_delegate.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "media/base/audio_decoder_config.h"
+#include "media/base/cdm_key_information.h"
#include "media/base/data_buffer.h"
#include "media/base/decoder_buffer.h"
+#include "media/base/key_systems.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
namespace content {
-scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create(
+void PpapiDecryptor::Create(
const std::string& key_system,
const GURL& security_origin,
+ bool allow_distinctive_identifier,
+ bool allow_persistent_state,
const CreatePepperCdmCB& create_pepper_cdm_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 media::LegacySessionErrorCB& legacy_session_error_cb,
const media::SessionKeysChangeCB& session_keys_change_cb,
- const media::SessionExpirationUpdateCB& session_expiration_update_cb) {
- std::string plugin_type = GetPepperType(key_system);
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb,
+ const media::CdmCreatedCB& cdm_created_cb) {
+ std::string plugin_type = media::GetPepperType(key_system);
DCHECK(!plugin_type.empty());
scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper =
create_pepper_cdm_cb.Run(plugin_type, security_origin);
if (!pepper_cdm_wrapper) {
DLOG(ERROR) << "Plugin instance creation failed.";
- return scoped_ptr<PpapiDecryptor>();
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE, base::Bind(cdm_created_cb, nullptr,
+ "Plugin instance creation failed."));
+ return;
}
- return scoped_ptr<PpapiDecryptor>(
- new PpapiDecryptor(key_system,
- pepper_cdm_wrapper.Pass(),
- session_message_cb,
- session_ready_cb,
- session_closed_cb,
- session_error_cb,
- session_keys_change_cb,
- session_expiration_update_cb));
+ scoped_ptr<PpapiDecryptor> ppapi_decryptor(
+ new PpapiDecryptor(pepper_cdm_wrapper.Pass(), session_message_cb,
+ session_closed_cb, legacy_session_error_cb,
+ session_keys_change_cb, session_expiration_update_cb));
+
+ // PpapiDecryptor ownership passed to the promise, but keep a copy in order
+ // to call InitializeCdm().
+ PpapiDecryptor* ppapi_decryptor_copy = ppapi_decryptor.get();
+ scoped_ptr<CdmInitializedPromise> promise(
+ new CdmInitializedPromise(cdm_created_cb, ppapi_decryptor.Pass()));
+ ppapi_decryptor_copy->InitializeCdm(key_system, allow_distinctive_identifier,
+ allow_persistent_state, promise.Pass());
}
PpapiDecryptor::PpapiDecryptor(
- const std::string& key_system,
scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper,
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 media::LegacySessionErrorCB& legacy_session_error_cb,
const media::SessionKeysChangeCB& session_keys_change_cb,
const media::SessionExpirationUpdateCB& session_expiration_update_cb)
: pepper_cdm_wrapper_(pepper_cdm_wrapper.Pass()),
session_message_cb_(session_message_cb),
- session_ready_cb_(session_ready_cb),
session_closed_cb_(session_closed_cb),
- session_error_cb_(session_error_cb),
+ legacy_session_error_cb_(legacy_session_error_cb),
session_keys_change_cb_(session_keys_change_cb),
session_expiration_update_cb_(session_expiration_update_cb),
render_loop_proxy_(base::MessageLoopProxy::current()),
weak_ptr_factory_(this) {
DCHECK(pepper_cdm_wrapper_.get());
DCHECK(!session_message_cb_.is_null());
- DCHECK(!session_ready_cb_.is_null());
DCHECK(!session_closed_cb_.is_null());
- DCHECK(!session_error_cb_.is_null());
+ DCHECK(!legacy_session_error_cb_.is_null());
DCHECK(!session_keys_change_cb.is_null());
DCHECK(!session_expiration_update_cb.is_null());
+}
+
+PpapiDecryptor::~PpapiDecryptor() {
+ pepper_cdm_wrapper_.reset();
+}
+void PpapiDecryptor::InitializeCdm(
+ const std::string& key_system,
+ bool allow_distinctive_identifier,
+ bool allow_persistent_state,
+ scoped_ptr<media::SimpleCdmPromise> promise) {
base::WeakPtr<PpapiDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr();
CdmDelegate()->Initialize(
- key_system,
+ key_system, allow_distinctive_identifier, allow_persistent_state,
base::Bind(&PpapiDecryptor::OnSessionMessage, weak_this),
- base::Bind(&PpapiDecryptor::OnSessionReady, weak_this),
base::Bind(&PpapiDecryptor::OnSessionClosed, weak_this),
- base::Bind(&PpapiDecryptor::OnSessionError, weak_this),
+ base::Bind(&PpapiDecryptor::OnLegacySessionError, weak_this),
base::Bind(&PpapiDecryptor::OnSessionKeysChange, weak_this),
base::Bind(&PpapiDecryptor::OnSessionExpirationUpdate, weak_this),
- base::Bind(&PpapiDecryptor::OnFatalPluginError, weak_this));
-}
-
-PpapiDecryptor::~PpapiDecryptor() {
- pepper_cdm_wrapper_.reset();
+ base::Bind(&PpapiDecryptor::OnFatalPluginError, weak_this),
+ promise.Pass());
}
void PpapiDecryptor::SetServerCertificate(
- const uint8* certificate_data,
- int certificate_data_length,
+ const std::vector<uint8_t>& certificate,
scoped_ptr<media::SimpleCdmPromise> promise) {
DVLOG(2) << __FUNCTION__;
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
@@ -105,15 +116,13 @@ void PpapiDecryptor::SetServerCertificate(
return;
}
- CdmDelegate()->SetServerCertificate(
- certificate_data, certificate_data_length, promise.Pass());
+ CdmDelegate()->SetServerCertificate(certificate, promise.Pass());
}
-void PpapiDecryptor::CreateSession(
- const std::string& init_data_type,
- const uint8* init_data,
- int init_data_length,
+void PpapiDecryptor::CreateSessionAndGenerateRequest(
SessionType session_type,
+ media::EmeInitDataType init_data_type,
+ const std::vector<uint8_t>& init_data,
scoped_ptr<media::NewSessionCdmPromise> promise) {
DVLOG(2) << __FUNCTION__;
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
@@ -123,15 +132,13 @@ void PpapiDecryptor::CreateSession(
return;
}
- CdmDelegate()->CreateSession(init_data_type,
- init_data,
- init_data_length,
- session_type,
- promise.Pass());
+ CdmDelegate()->CreateSessionAndGenerateRequest(session_type, init_data_type,
+ init_data, promise.Pass());
}
void PpapiDecryptor::LoadSession(
- const std::string& web_session_id,
+ SessionType session_type,
+ const std::string& session_id,
scoped_ptr<media::NewSessionCdmPromise> promise) {
DVLOG(2) << __FUNCTION__;
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
@@ -140,13 +147,12 @@ void PpapiDecryptor::LoadSession(
promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist.");
return;
}
- CdmDelegate()->LoadSession(web_session_id, promise.Pass());
+ CdmDelegate()->LoadSession(session_type, session_id, promise.Pass());
}
void PpapiDecryptor::UpdateSession(
- const std::string& web_session_id,
- const uint8* response,
- int response_length,
+ const std::string& session_id,
+ const std::vector<uint8_t>& response,
scoped_ptr<media::SimpleCdmPromise> promise) {
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
@@ -154,11 +160,10 @@ void PpapiDecryptor::UpdateSession(
promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist.");
return;
}
- CdmDelegate()->UpdateSession(web_session_id, response, response_length,
- promise.Pass());
+ CdmDelegate()->UpdateSession(session_id, response, promise.Pass());
}
-void PpapiDecryptor::CloseSession(const std::string& web_session_id,
+void PpapiDecryptor::CloseSession(const std::string& session_id,
scoped_ptr<media::SimpleCdmPromise> promise) {
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
@@ -167,11 +172,11 @@ void PpapiDecryptor::CloseSession(const std::string& web_session_id,
return;
}
- CdmDelegate()->CloseSession(web_session_id, promise.Pass());
+ CdmDelegate()->CloseSession(session_id, promise.Pass());
}
void PpapiDecryptor::RemoveSession(
- const std::string& web_session_id,
+ const std::string& session_id,
scoped_ptr<media::SimpleCdmPromise> promise) {
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
@@ -180,25 +185,21 @@ void PpapiDecryptor::RemoveSession(
return;
}
- CdmDelegate()->RemoveSession(web_session_id, promise.Pass());
+ CdmDelegate()->RemoveSession(session_id, promise.Pass());
}
-void PpapiDecryptor::GetUsableKeyIds(const std::string& web_session_id,
- scoped_ptr<media::KeyIdsPromise> promise) {
- DCHECK(render_loop_proxy_->BelongsToCurrentThread());
-
- if (!CdmDelegate()) {
- promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist.");
- return;
- }
-
- CdmDelegate()->GetUsableKeyIds(web_session_id, promise.Pass());
+media::CdmContext* PpapiDecryptor::GetCdmContext() {
+ return this;
}
media::Decryptor* PpapiDecryptor::GetDecryptor() {
return this;
}
+int PpapiDecryptor::GetCdmId() const {
+ return kInvalidCdmId;
+}
+
void PpapiDecryptor::RegisterNewKeyCB(StreamType stream_type,
const NewKeyCB& new_key_cb) {
if (!render_loop_proxy_->BelongsToCurrentThread()) {
@@ -330,7 +331,7 @@ void PpapiDecryptor::DecryptAndDecodeAudio(
DVLOG(3) << __FUNCTION__;
if (!CdmDelegate() ||
!CdmDelegate()->DecryptAndDecodeAudio(encrypted, audio_decode_cb)) {
- audio_decode_cb.Run(kError, AudioBuffers());
+ audio_decode_cb.Run(kError, AudioFrames());
}
}
@@ -400,15 +401,18 @@ void PpapiDecryptor::OnDecoderInitialized(StreamType stream_type,
}
}
-void PpapiDecryptor::OnSessionMessage(const std::string& web_session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url) {
+void PpapiDecryptor::OnSessionMessage(const std::string& session_id,
+ MessageType message_type,
+ const std::vector<uint8_t>& message,
+ const GURL& legacy_destination_url) {
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
- session_message_cb_.Run(web_session_id, message, destination_url);
+ session_message_cb_.Run(session_id, message_type, message,
+ legacy_destination_url);
}
-void PpapiDecryptor::OnSessionKeysChange(const std::string& web_session_id,
- bool has_additional_usable_key) {
+void PpapiDecryptor::OnSessionKeysChange(const std::string& session_id,
+ bool has_additional_usable_key,
+ media::CdmKeysInfo keys_info) {
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
// TODO(jrummell): Handling resume playback should be done in the media
@@ -416,33 +420,30 @@ void PpapiDecryptor::OnSessionKeysChange(const std::string& web_session_id,
if (has_additional_usable_key)
AttemptToResumePlayback();
- session_keys_change_cb_.Run(web_session_id, has_additional_usable_key);
+ session_keys_change_cb_.Run(session_id, has_additional_usable_key,
+ keys_info.Pass());
}
void PpapiDecryptor::OnSessionExpirationUpdate(
- const std::string& web_session_id,
+ const std::string& session_id,
const base::Time& new_expiry_time) {
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
- session_expiration_update_cb_.Run(web_session_id, new_expiry_time);
-}
-
-void PpapiDecryptor::OnSessionReady(const std::string& web_session_id) {
- DCHECK(render_loop_proxy_->BelongsToCurrentThread());
- session_ready_cb_.Run(web_session_id);
+ session_expiration_update_cb_.Run(session_id, new_expiry_time);
}
-void PpapiDecryptor::OnSessionClosed(const std::string& web_session_id) {
+void PpapiDecryptor::OnSessionClosed(const std::string& session_id) {
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
- session_closed_cb_.Run(web_session_id);
+ session_closed_cb_.Run(session_id);
}
-void PpapiDecryptor::OnSessionError(const std::string& web_session_id,
- MediaKeys::Exception exception_code,
- uint32 system_code,
- const std::string& error_description) {
+void PpapiDecryptor::OnLegacySessionError(
+ const std::string& session_id,
+ MediaKeys::Exception exception_code,
+ uint32_t system_code,
+ const std::string& error_description) {
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
- session_error_cb_.Run(
- web_session_id, exception_code, system_code, error_description);
+ legacy_session_error_cb_.Run(session_id, exception_code, system_code,
+ error_description);
}
void PpapiDecryptor::AttemptToResumePlayback() {
diff --git a/chromium/content/renderer/media/crypto/ppapi_decryptor.h b/chromium/content/renderer/media/crypto/ppapi_decryptor.h
index 39c38c210f3..a4f26b5ac32 100644
--- a/chromium/content/renderer/media/crypto/ppapi_decryptor.h
+++ b/chromium/content/renderer/media/crypto/ppapi_decryptor.h
@@ -12,6 +12,8 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/renderer/media/crypto/pepper_cdm_wrapper.h"
+#include "media/base/cdm_context.h"
+#include "media/base/cdm_factory.h"
#include "media/base/decryptor.h"
#include "media/base/media_keys.h"
#include "media/base/video_decoder_config.h"
@@ -29,44 +31,49 @@ class PepperPluginInstanceImpl;
// PpapiDecryptor implements media::MediaKeys and media::Decryptor and forwards
// all calls to the PluginInstance.
// This class should always be created & destroyed on the main renderer thread.
-class PpapiDecryptor : public media::MediaKeys, public media::Decryptor {
+class PpapiDecryptor : public media::MediaKeys,
+ public media::CdmContext,
+ public media::Decryptor {
public:
- static scoped_ptr<PpapiDecryptor> Create(
+ static void Create(
const std::string& key_system,
const GURL& security_origin,
+ bool allow_distinctive_identifier,
+ bool allow_persistent_state,
const CreatePepperCdmCB& create_pepper_cdm_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 media::LegacySessionErrorCB& legacy_session_error_cb,
const media::SessionKeysChangeCB& session_keys_change_cb,
- const media::SessionExpirationUpdateCB& session_expiration_update_cb);
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb,
+ const media::CdmCreatedCB& cdm_created_cb);
~PpapiDecryptor() override;
// media::MediaKeys implementation.
void SetServerCertificate(
- const uint8* certificate_data,
- int certificate_data_length,
+ const std::vector<uint8_t>& certificate,
scoped_ptr<media::SimpleCdmPromise> promise) override;
- void CreateSession(const std::string& init_data_type,
- const uint8* init_data,
- int init_data_length,
- SessionType session_type,
- scoped_ptr<media::NewSessionCdmPromise> promise) override;
- void LoadSession(const std::string& web_session_id,
+ void CreateSessionAndGenerateRequest(
+ SessionType session_type,
+ media::EmeInitDataType init_data_type,
+ const std::vector<uint8_t>& init_data,
+ scoped_ptr<media::NewSessionCdmPromise> promise) override;
+ void LoadSession(SessionType session_type,
+ const std::string& session_id,
scoped_ptr<media::NewSessionCdmPromise> promise) override;
- void UpdateSession(const std::string& web_session_id,
- const uint8* response,
- int response_length,
+ void UpdateSession(const std::string& session_id,
+ const std::vector<uint8_t>& response,
scoped_ptr<media::SimpleCdmPromise> promise) override;
- void CloseSession(const std::string& web_session_id,
+ void CloseSession(const std::string& session_id,
scoped_ptr<media::SimpleCdmPromise> promise) override;
- void RemoveSession(const std::string& web_session_id,
+ void RemoveSession(const std::string& session_id,
scoped_ptr<media::SimpleCdmPromise> promise) override;
- void GetUsableKeyIds(const std::string& web_session_id,
- scoped_ptr<media::KeyIdsPromise> promise) override;
+ CdmContext* GetCdmContext() override;
+
+ // media::CdmContext implementation.
Decryptor* GetDecryptor() override;
+ int GetCdmId() const override;
// media::Decryptor implementation.
void RegisterNewKeyCB(StreamType stream_type,
@@ -90,31 +97,35 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor {
private:
PpapiDecryptor(
- const std::string& key_system,
scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper,
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 media::LegacySessionErrorCB& legacy_session_error_cb,
const media::SessionKeysChangeCB& session_keys_change_cb,
const media::SessionExpirationUpdateCB& session_expiration_update_cb);
+ void InitializeCdm(const std::string& key_system,
+ bool allow_distinctive_identifier,
+ bool allow_persistent_state,
+ scoped_ptr<media::SimpleCdmPromise> promise);
+
void OnDecoderInitialized(StreamType stream_type, bool success);
// Callbacks for |plugin_cdm_delegate_| to fire session events.
- void OnSessionMessage(const std::string& web_session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url);
- void OnSessionKeysChange(const std::string& web_session_id,
- bool has_additional_usable_key);
- void OnSessionExpirationUpdate(const std::string& web_session_id,
+ void OnSessionMessage(const std::string& session_id,
+ MediaKeys::MessageType message_type,
+ const std::vector<uint8_t>& message,
+ const GURL& legacy_destination_url);
+ void OnSessionKeysChange(const std::string& session_id,
+ bool has_additional_usable_key,
+ media::CdmKeysInfo keys_info);
+ void OnSessionExpirationUpdate(const std::string& 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,
- MediaKeys::Exception exception_code,
- uint32 system_code,
- const std::string& error_description);
+ void OnSessionClosed(const std::string& session_id);
+ void OnLegacySessionError(const std::string& session_id,
+ MediaKeys::Exception exception_code,
+ uint32_t system_code,
+ const std::string& error_description);
void AttemptToResumePlayback();
@@ -131,9 +142,8 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor {
// Callbacks for firing session events.
media::SessionMessageCB session_message_cb_;
- media::SessionReadyCB session_ready_cb_;
media::SessionClosedCB session_closed_cb_;
- media::SessionErrorCB session_error_cb_;
+ media::LegacySessionErrorCB legacy_session_error_cb_;
media::SessionKeysChangeCB session_keys_change_cb_;
media::SessionExpirationUpdateCB session_expiration_update_cb_;
diff --git a/chromium/content/renderer/media/crypto/proxy_decryptor.cc b/chromium/content/renderer/media/crypto/proxy_decryptor.cc
deleted file mode 100644
index 44a30fd1f84..00000000000
--- a/chromium/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/chromium/content/renderer/media/crypto/proxy_decryptor.h b/chromium/content/renderer/media/crypto/proxy_decryptor.h
deleted file mode 100644
index 62f2e8eb884..00000000000
--- a/chromium/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/chromium/content/renderer/media/crypto/proxy_media_keys.cc b/chromium/content/renderer/media/crypto/proxy_media_keys.cc
index e62c6cea1fd..4092324d661 100644
--- a/chromium/content/renderer/media/crypto/proxy_media_keys.cc
+++ b/chromium/content/renderer/media/crypto/proxy_media_keys.cc
@@ -9,287 +9,207 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/stl_util.h"
-#include "content/renderer/media/crypto/key_systems.h"
+#include "content/renderer/media/crypto/cdm_initialized_promise.h"
#include "content/renderer/media/crypto/renderer_cdm_manager.h"
+#include "media/base/cdm_key_information.h"
#include "media/base/cdm_promise.h"
+#include "media/base/key_systems.h"
namespace content {
-scoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create(
+void ProxyMediaKeys::Create(
const std::string& key_system,
const GURL& security_origin,
+ bool use_hw_secure_codecs,
RendererCdmManager* manager,
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 media::LegacySessionErrorCB& legacy_session_error_cb,
const media::SessionKeysChangeCB& session_keys_change_cb,
- const media::SessionExpirationUpdateCB& session_expiration_update_cb) {
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb,
+ const media::CdmCreatedCB& cdm_created_cb) {
DCHECK(manager);
+ scoped_ptr<ProxyMediaKeys> proxy_media_keys(new ProxyMediaKeys(
+ manager, session_message_cb, session_closed_cb, legacy_session_error_cb,
+ session_keys_change_cb, session_expiration_update_cb));
- // TODO(jrummell): Add support for SessionKeysChangeCB and
- // SessionExpirationUpdateCB.
- scoped_ptr<ProxyMediaKeys> proxy_media_keys(
- new ProxyMediaKeys(manager,
- session_message_cb,
- session_ready_cb,
- session_closed_cb,
- session_error_cb));
- proxy_media_keys->InitializeCdm(key_system, security_origin);
- return proxy_media_keys.Pass();
+ // ProxyMediaKeys ownership passed to the promise, but keep a copy in order
+ // to call InitializeCdm().
+ ProxyMediaKeys* proxy_media_keys_copy = proxy_media_keys.get();
+ scoped_ptr<CdmInitializedPromise> promise(
+ new CdmInitializedPromise(cdm_created_cb, proxy_media_keys.Pass()));
+ proxy_media_keys_copy->InitializeCdm(key_system, security_origin,
+ use_hw_secure_codecs, promise.Pass());
}
ProxyMediaKeys::~ProxyMediaKeys() {
manager_->DestroyCdm(cdm_id_);
manager_->UnregisterMediaKeys(cdm_id_);
-
- // Reject any outstanding promises.
- for (PromiseMap::iterator it = session_id_to_promise_map_.begin();
- it != session_id_to_promise_map_.end();
- ++it) {
- it->second->reject(
- media::MediaKeys::NOT_SUPPORTED_ERROR, 0, "The operation was aborted.");
- }
- session_id_to_promise_map_.clear();
+ cdm_promise_adapter_.Clear();
}
void ProxyMediaKeys::SetServerCertificate(
- const uint8* certificate_data,
- int certificate_data_length,
+ const std::vector<uint8_t>& certificate,
scoped_ptr<media::SimpleCdmPromise> promise) {
- promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented.");
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+ manager_->SetServerCertificate(cdm_id_, promise_id, certificate);
}
-void ProxyMediaKeys::CreateSession(
- const std::string& init_data_type,
- const uint8* init_data,
- int init_data_length,
+void ProxyMediaKeys::CreateSessionAndGenerateRequest(
SessionType session_type,
+ media::EmeInitDataType init_data_type,
+ const std::vector<uint8_t>& init_data,
scoped_ptr<media::NewSessionCdmPromise> promise) {
+ if (session_type != media::MediaKeys::TEMPORARY_SESSION) {
+ promise->reject(NOT_SUPPORTED_ERROR, 0,
+ "Only the temporary session type is supported.");
+ return;
+ }
+
// TODO(xhwang): Move these checks up to blink and DCHECK here.
// See http://crbug.com/342510
- CdmHostMsg_CreateSession_ContentType create_session_content_type;
- if (init_data_type == "cenc") {
- create_session_content_type = CREATE_SESSION_TYPE_MP4;
- } else if (init_data_type == "webm") {
- create_session_content_type = CREATE_SESSION_TYPE_WEBM;
- } else {
- DLOG(ERROR) << "Unsupported EME CreateSession content type of "
- << init_data_type;
- promise->reject(
- NOT_SUPPORTED_ERROR,
- 0,
- "Unsupported EME CreateSession init data type of " + init_data_type);
- return;
+ CdmHostMsg_CreateSession_InitDataType create_session_init_data_type =
+ INIT_DATA_TYPE_WEBM;
+ switch (init_data_type) {
+ case media::EmeInitDataType::CENC:
+ create_session_init_data_type = INIT_DATA_TYPE_CENC;
+ break;
+ case media::EmeInitDataType::WEBM:
+ create_session_init_data_type = INIT_DATA_TYPE_WEBM;
+ break;
+ case media::EmeInitDataType::KEYIDS:
+ case media::EmeInitDataType::UNKNOWN:
+ DLOG(ERROR) << "Unsupported EME CreateSession init data type";
+ promise->reject(NOT_SUPPORTED_ERROR, 0,
+ "Unsupported EME CreateSession init data type");
+ return;
}
- uint32 session_id = CreateSessionId();
- SavePromise(session_id, promise.Pass());
- manager_->CreateSession(
- cdm_id_,
- session_id,
- create_session_content_type,
- std::vector<uint8>(init_data, init_data + init_data_length));
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+ manager_->CreateSessionAndGenerateRequest(
+ cdm_id_, promise_id, create_session_init_data_type, init_data);
}
void ProxyMediaKeys::LoadSession(
- const std::string& web_session_id,
+ SessionType session_type,
+ const std::string& session_id,
scoped_ptr<media::NewSessionCdmPromise> promise) {
// TODO(xhwang): Check key system and platform support for LoadSession in
- // blink and add NOTREACHED() here.
+ // blink and add NOTREACHED() here. See http://crbug.com/384152
DLOG(ERROR) << "ProxyMediaKeys doesn't support session loading.";
promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported.");
}
void ProxyMediaKeys::UpdateSession(
- const std::string& web_session_id,
- const uint8* response,
- int response_length,
+ const std::string& session_id,
+ const std::vector<uint8_t>& response,
scoped_ptr<media::SimpleCdmPromise> promise) {
- uint32 session_id = LookupSessionId(web_session_id);
- if (!session_id) {
- promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist.");
- return;
- }
-
- SavePromise(session_id, promise.Pass());
- manager_->UpdateSession(
- cdm_id_,
- session_id,
- std::vector<uint8>(response, response + response_length));
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+ manager_->UpdateSession(cdm_id_, promise_id, session_id, response);
}
-void ProxyMediaKeys::CloseSession(const std::string& web_session_id,
+void ProxyMediaKeys::CloseSession(const std::string& session_id,
scoped_ptr<media::SimpleCdmPromise> promise) {
- uint32 session_id = LookupSessionId(web_session_id);
- if (!session_id) {
- promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist.");
- return;
- }
-
- SavePromise(session_id, promise.Pass());
- manager_->ReleaseSession(cdm_id_, session_id);
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+ manager_->CloseSession(cdm_id_, promise_id, session_id);
}
void ProxyMediaKeys::RemoveSession(
- const std::string& web_session_id,
+ const std::string& session_id,
scoped_ptr<media::SimpleCdmPromise> promise) {
- promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented.");
+ // TODO(xhwang): Check key system and platform support for LoadSession in
+ // blink and add NOTREACHED() here. See http://crbug.com/384152
+ promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() not supported.");
}
-void ProxyMediaKeys::GetUsableKeyIds(const std::string& web_session_id,
- scoped_ptr<media::KeyIdsPromise> promise) {
- promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented.");
+media::CdmContext* ProxyMediaKeys::GetCdmContext() {
+ return this;
+}
+
+media::Decryptor* ProxyMediaKeys::GetDecryptor() {
+ return nullptr;
}
int ProxyMediaKeys::GetCdmId() const {
return cdm_id_;
}
-void ProxyMediaKeys::OnSessionCreated(uint32 session_id,
- const std::string& web_session_id) {
- AssignWebSessionId(session_id, web_session_id);
- scoped_ptr<media::CdmPromise> promise = TakePromise(session_id);
- if (promise) {
- media::NewSessionCdmPromise* session_promise(
- static_cast<media::NewSessionCdmPromise*>(promise.get()));
- session_promise->resolve(web_session_id);
- }
+void ProxyMediaKeys::OnSessionMessage(
+ const std::string& session_id,
+ media::MediaKeys::MessageType message_type,
+ const std::vector<uint8_t>& message,
+ const GURL& legacy_destination_url) {
+ session_message_cb_.Run(session_id, message_type, message,
+ legacy_destination_url);
}
-void ProxyMediaKeys::OnSessionMessage(uint32 session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url) {
- session_message_cb_.Run(
- LookupWebSessionId(session_id), message, destination_url);
+void ProxyMediaKeys::OnSessionClosed(const std::string& session_id) {
+ session_closed_cb_.Run(session_id);
}
-void ProxyMediaKeys::OnSessionReady(uint32 session_id) {
- scoped_ptr<media::CdmPromise> promise = TakePromise(session_id);
- if (promise) {
- media::SimpleCdmPromise* simple_promise(
- static_cast<media::SimpleCdmPromise*>(promise.get()));
- simple_promise->resolve();
- } else {
- // Still needed for keyadded.
- const std::string web_session_id = LookupWebSessionId(session_id);
- session_ready_cb_.Run(web_session_id);
- }
+void ProxyMediaKeys::OnLegacySessionError(const std::string& session_id,
+ media::MediaKeys::Exception exception,
+ uint32_t system_code,
+ const std::string& error_message) {
+ legacy_session_error_cb_.Run(session_id, exception, system_code,
+ error_message);
}
-void ProxyMediaKeys::OnSessionClosed(uint32 session_id) {
- const std::string web_session_id = LookupWebSessionId(session_id);
- DropWebSessionId(web_session_id);
- scoped_ptr<media::CdmPromise> promise = TakePromise(session_id);
- if (promise) {
- media::SimpleCdmPromise* simple_promise(
- static_cast<media::SimpleCdmPromise*>(promise.get()));
- simple_promise->resolve();
- } else {
- // It is possible for the CDM to close a session independent of a
- // Release() request.
- session_closed_cb_.Run(web_session_id);
- }
+void ProxyMediaKeys::OnSessionKeysChange(const std::string& session_id,
+ bool has_additional_usable_key,
+ media::CdmKeysInfo keys_info) {
+ session_keys_change_cb_.Run(session_id, has_additional_usable_key,
+ keys_info.Pass());
}
-void ProxyMediaKeys::OnSessionError(uint32 session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code) {
- const std::string web_session_id = LookupWebSessionId(session_id);
- media::MediaKeys::Exception exception_code;
- switch (error_code) {
- case media::MediaKeys::kClientError:
- exception_code = media::MediaKeys::CLIENT_ERROR;
- break;
- case media::MediaKeys::kOutputError:
- exception_code = media::MediaKeys::OUTPUT_ERROR;
- break;
- case media::MediaKeys::kUnknownError:
- default:
- exception_code = media::MediaKeys::UNKNOWN_ERROR;
- break;
- }
+void ProxyMediaKeys::OnSessionExpirationUpdate(
+ const std::string& session_id,
+ const base::Time& new_expiry_time) {
+ session_expiration_update_cb_.Run(session_id, new_expiry_time);
+}
- scoped_ptr<media::CdmPromise> promise = TakePromise(session_id);
- if (promise) {
- promise->reject(exception_code, system_code, std::string());
- return;
- }
+void ProxyMediaKeys::OnPromiseResolved(uint32_t promise_id) {
+ cdm_promise_adapter_.ResolvePromise(promise_id);
+}
- // Errors generally happen in response to a request, but it is possible
- // for something bad to happen in the CDM and it needs to tell the client.
- session_error_cb_.Run(
- web_session_id, exception_code, system_code, std::string());
+void ProxyMediaKeys::OnPromiseResolvedWithSession(
+ uint32_t promise_id,
+ const std::string& session_id) {
+ cdm_promise_adapter_.ResolvePromise(promise_id, session_id);
+}
+
+void ProxyMediaKeys::OnPromiseRejected(uint32_t promise_id,
+ media::MediaKeys::Exception exception,
+ uint32_t system_code,
+ const std::string& error_message) {
+ cdm_promise_adapter_.RejectPromise(promise_id, exception, system_code,
+ error_message);
}
ProxyMediaKeys::ProxyMediaKeys(
RendererCdmManager* manager,
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 media::LegacySessionErrorCB& legacy_session_error_cb,
+ const media::SessionKeysChangeCB& session_keys_change_cb,
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb)
: manager_(manager),
session_message_cb_(session_message_cb),
- session_ready_cb_(session_ready_cb),
session_closed_cb_(session_closed_cb),
- session_error_cb_(session_error_cb),
- next_session_id_(1) {
+ legacy_session_error_cb_(legacy_session_error_cb),
+ session_keys_change_cb_(session_keys_change_cb),
+ session_expiration_update_cb_(session_expiration_update_cb) {
cdm_id_ = manager->RegisterMediaKeys(this);
}
-void ProxyMediaKeys::InitializeCdm(const std::string& key_system,
- const GURL& security_origin) {
- manager_->InitializeCdm(cdm_id_, this, key_system, security_origin);
-}
-
-uint32_t ProxyMediaKeys::CreateSessionId() {
- return next_session_id_++;
-}
-
-void ProxyMediaKeys::AssignWebSessionId(uint32_t session_id,
- const std::string& web_session_id) {
- DCHECK(!ContainsKey(web_session_to_session_id_map_, web_session_id));
- DCHECK(session_id);
- web_session_to_session_id_map_.insert(
- std::make_pair(web_session_id, session_id));
-}
-
-uint32_t ProxyMediaKeys::LookupSessionId(
- const std::string& web_session_id) const {
- SessionIdMap::const_iterator it =
- web_session_to_session_id_map_.find(web_session_id);
- return (it != web_session_to_session_id_map_.end()) ? it->second : 0;
-}
-
-std::string ProxyMediaKeys::LookupWebSessionId(uint32_t session_id) const {
- for (SessionIdMap::const_iterator it = web_session_to_session_id_map_.begin();
- it != web_session_to_session_id_map_.end();
- ++it) {
- if (it->second == session_id)
- return it->first;
- }
- // Possible to get an error creating a session, so no |web_session_id|
- // available.
- return std::string();
-}
-
-void ProxyMediaKeys::DropWebSessionId(const std::string& web_session_id) {
- web_session_to_session_id_map_.erase(web_session_id);
-}
-
-void ProxyMediaKeys::SavePromise(uint32_t session_id,
- scoped_ptr<media::CdmPromise> promise) {
- // Should only be one promise outstanding for any |session_id|.
- DCHECK(!ContainsKey(session_id_to_promise_map_, session_id));
- session_id_to_promise_map_.add(session_id, promise.Pass());
-}
-
-scoped_ptr<media::CdmPromise> ProxyMediaKeys::TakePromise(uint32_t session_id) {
- PromiseMap::iterator it = session_id_to_promise_map_.find(session_id);
- // May not be a promise associated with this session for asynchronous events.
- if (it == session_id_to_promise_map_.end())
- return scoped_ptr<media::CdmPromise>();
- return session_id_to_promise_map_.take_and_erase(it);
+void ProxyMediaKeys::InitializeCdm(
+ const std::string& key_system,
+ const GURL& security_origin,
+ bool use_hw_secure_codecs,
+ scoped_ptr<media::SimpleCdmPromise> promise) {
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass());
+ manager_->InitializeCdm(cdm_id_, promise_id, this, key_system,
+ security_origin, use_hw_secure_codecs);
}
} // namespace content
diff --git a/chromium/content/renderer/media/crypto/proxy_media_keys.h b/chromium/content/renderer/media/crypto/proxy_media_keys.h
index 6b4df648276..b256dfa5e29 100644
--- a/chromium/content/renderer/media/crypto/proxy_media_keys.h
+++ b/chromium/content/renderer/media/crypto/proxy_media_keys.h
@@ -7,11 +7,15 @@
#include <map>
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/containers/scoped_ptr_hash_map.h"
+#include "media/base/cdm_context.h"
+#include "media/base/cdm_factory.h"
#include "media/base/cdm_promise.h"
+#include "media/base/cdm_promise_adapter.h"
#include "media/base/media_keys.h"
class GURL;
@@ -21,114 +25,95 @@ namespace content {
class RendererCdmManager;
// A MediaKeys proxy that wraps the EME part of RendererCdmManager.
-class ProxyMediaKeys : public media::MediaKeys {
+class ProxyMediaKeys : public media::MediaKeys, public media::CdmContext {
public:
- static scoped_ptr<ProxyMediaKeys> Create(
+ static void Create(
const std::string& key_system,
const GURL& security_origin,
+ bool use_hw_secure_codecs,
RendererCdmManager* manager,
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 media::LegacySessionErrorCB& legacy_session_error_cb,
const media::SessionKeysChangeCB& session_keys_change_cb,
- const media::SessionExpirationUpdateCB& session_expiration_update_cb);
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb,
+ const media::CdmCreatedCB& cdm_created_cb);
- virtual ~ProxyMediaKeys();
+ ~ProxyMediaKeys() override;
// MediaKeys implementation.
- virtual void SetServerCertificate(
- const uint8* certificate_data,
- int certificate_data_length,
+ void SetServerCertificate(
+ const std::vector<uint8_t>& certificate,
scoped_ptr<media::SimpleCdmPromise> promise) override;
- virtual void CreateSession(
- const std::string& init_data_type,
- const uint8* init_data,
- int init_data_length,
+ void CreateSessionAndGenerateRequest(
SessionType session_type,
+ media::EmeInitDataType init_data_type,
+ const std::vector<uint8_t>& init_data,
scoped_ptr<media::NewSessionCdmPromise> promise) override;
- virtual void LoadSession(
- const std::string& web_session_id,
- scoped_ptr<media::NewSessionCdmPromise> promise) override;
- virtual void UpdateSession(
- const std::string& web_session_id,
- const uint8* response,
- int response_length,
- scoped_ptr<media::SimpleCdmPromise> promise) override;
- virtual void CloseSession(
- const std::string& web_session_id,
- scoped_ptr<media::SimpleCdmPromise> promise) override;
- virtual void RemoveSession(
- const std::string& web_session_id,
- scoped_ptr<media::SimpleCdmPromise> promise) override;
- virtual void GetUsableKeyIds(
- const std::string& web_session_id,
- scoped_ptr<media::KeyIdsPromise> promise) override;
- virtual int GetCdmId() const override;
+ void LoadSession(SessionType session_type,
+ const std::string& session_id,
+ scoped_ptr<media::NewSessionCdmPromise> promise) override;
+ void UpdateSession(const std::string& session_id,
+ const std::vector<uint8_t>& response,
+ scoped_ptr<media::SimpleCdmPromise> promise) override;
+ void CloseSession(const std::string& session_id,
+ scoped_ptr<media::SimpleCdmPromise> promise) override;
+ void RemoveSession(const std::string& session_id,
+ scoped_ptr<media::SimpleCdmPromise> promise) override;
+ media::CdmContext* GetCdmContext() override;
+
+ // media::CdmContext implementation.
+ media::Decryptor* GetDecryptor() override;
+ int GetCdmId() const override;
// Callbacks.
- void OnSessionCreated(uint32 session_id, const std::string& web_session_id);
- void OnSessionMessage(uint32 session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url);
- void OnSessionReady(uint32 session_id);
- void OnSessionClosed(uint32 session_id);
- void OnSessionError(uint32 session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code);
+ void OnSessionMessage(const std::string& session_id,
+ media::MediaKeys::MessageType message_type,
+ const std::vector<uint8_t>& message,
+ const GURL& legacy_destination_url);
+ void OnSessionClosed(const std::string& session_id);
+ void OnLegacySessionError(const std::string& session_id,
+ media::MediaKeys::Exception exception,
+ uint32_t system_code,
+ const std::string& error_message);
+ void OnSessionKeysChange(const std::string& session_id,
+ bool has_additional_usable_key,
+ media::CdmKeysInfo keys_info);
+ void OnSessionExpirationUpdate(const std::string& session_id,
+ const base::Time& new_expiry_time);
+
+ void OnPromiseResolved(uint32_t promise_id);
+ void OnPromiseResolvedWithSession(uint32_t promise_id,
+ const std::string& session_id);
+ void OnPromiseRejected(uint32_t promise_id,
+ media::MediaKeys::Exception exception,
+ uint32_t system_code,
+ const std::string& error_message);
private:
- // The Android-specific code that handles sessions uses integer session ids
- // (basically a reference id), but media::MediaKeys bases everything on
- // web_session_id (a string representing the actual session id as generated
- // by the CDM). SessionIdMap is used to map between the web_session_id and
- // the session_id used by the Android-specific code.
- typedef base::hash_map<std::string, uint32_t> SessionIdMap;
-
- // The following types keep track of Promises. The index is the
- // Android-specific session_id, so that returning results can be matched to
- // the corresponding promise.
- typedef base::ScopedPtrHashMap<uint32_t, media::CdmPromise> PromiseMap;
-
- ProxyMediaKeys(RendererCdmManager* manager,
- const media::SessionMessageCB& session_message_cb,
- const media::SessionReadyCB& session_ready_cb,
- const media::SessionClosedCB& session_closed_cb,
- const media::SessionErrorCB& session_error_cb);
+ ProxyMediaKeys(
+ RendererCdmManager* manager,
+ const media::SessionMessageCB& session_message_cb,
+ const media::SessionClosedCB& session_closed_cb,
+ const media::LegacySessionErrorCB& legacy_session_error_cb,
+ const media::SessionKeysChangeCB& session_keys_change_cb,
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb);
void InitializeCdm(const std::string& key_system,
- const GURL& security_origin);
-
- // These functions keep track of Android-specific session_ids <->
- // web_session_ids mappings.
- // TODO(jrummell): Remove this once the Android-specific code changes to
- // support string web session ids.
- uint32_t CreateSessionId();
- void AssignWebSessionId(uint32_t session_id,
- const std::string& web_session_id);
- uint32_t LookupSessionId(const std::string& web_session_id) const;
- std::string LookupWebSessionId(uint32_t session_id) const;
- void DropWebSessionId(const std::string& web_session_id);
-
- // Helper function to keep track of promises. Adding takes ownership of the
- // promise, transferred back to caller on take.
- void SavePromise(uint32_t session_id, scoped_ptr<media::CdmPromise> promise);
- scoped_ptr<media::CdmPromise> TakePromise(uint32_t session_id);
+ const GURL& security_origin,
+ bool use_hw_secure_codecs,
+ scoped_ptr<media::SimpleCdmPromise> promise);
RendererCdmManager* manager_;
int cdm_id_;
media::SessionMessageCB session_message_cb_;
- media::SessionReadyCB session_ready_cb_;
media::SessionClosedCB session_closed_cb_;
- media::SessionErrorCB session_error_cb_;
-
- // Android-specific. See comment above CreateSessionId().
- uint32_t next_session_id_;
- SessionIdMap web_session_to_session_id_map_;
+ media::LegacySessionErrorCB legacy_session_error_cb_;
+ media::SessionKeysChangeCB session_keys_change_cb_;
+ media::SessionExpirationUpdateCB session_expiration_update_cb_;
- // Keep track of outstanding promises. This map owns the promise object.
- PromiseMap session_id_to_promise_map_;
+ media::CdmPromiseAdapter cdm_promise_adapter_;
DISALLOW_COPY_AND_ASSIGN(ProxyMediaKeys);
};
diff --git a/chromium/content/renderer/media/crypto/render_cdm_factory.cc b/chromium/content/renderer/media/crypto/render_cdm_factory.cc
index 63fec99ed31..fe1a5dae2e9 100644
--- a/chromium/content/renderer/media/crypto/render_cdm_factory.cc
+++ b/chromium/content/renderer/media/crypto/render_cdm_factory.cc
@@ -4,11 +4,17 @@
#include "content/renderer/media/crypto/render_cdm_factory.h"
+#include "base/bind.h"
+#include "base/location.h"
#include "base/logging.h"
-#include "content/renderer/media/crypto/key_systems.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "media/base/cdm_config.h"
+#include "media/base/cdm_promise.h"
+#include "media/base/key_systems.h"
+#include "media/base/media_keys.h"
#include "media/cdm/aes_decryptor.h"
#include "url/gurl.h"
-
#if defined(ENABLE_PEPPER_CDMS)
#include "content/renderer/media/crypto/ppapi_decryptor.h"
#elif defined(ENABLE_BROWSER_CDMS)
@@ -17,66 +23,76 @@
namespace content {
-#if defined(ENABLE_PEPPER_CDMS)
RenderCdmFactory::RenderCdmFactory(
- const CreatePepperCdmCB& create_pepper_cdm_cb)
- : create_pepper_cdm_cb_(create_pepper_cdm_cb) {
-}
+#if defined(ENABLE_PEPPER_CDMS)
+ const CreatePepperCdmCB& create_pepper_cdm_cb,
#elif defined(ENABLE_BROWSER_CDMS)
-RenderCdmFactory::RenderCdmFactory(RendererCdmManager* manager)
- : manager_(manager) {
-}
-#else
-RenderCdmFactory::RenderCdmFactory() {
-}
+ RendererCdmManager* manager,
#endif // defined(ENABLE_PEPPER_CDMS)
+ RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame)
+#if defined(ENABLE_PEPPER_CDMS)
+ , create_pepper_cdm_cb_(create_pepper_cdm_cb)
+#elif defined(ENABLE_BROWSER_CDMS)
+ , manager_(manager)
+#endif // defined(ENABLE_PEPPER_CDMS)
+{
+}
RenderCdmFactory::~RenderCdmFactory() {
+ DCHECK(thread_checker_.CalledOnValidThread());
}
-scoped_ptr<media::MediaKeys> RenderCdmFactory::Create(
+void RenderCdmFactory::Create(
const std::string& key_system,
const GURL& security_origin,
+ const media::CdmConfig& cdm_config,
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 media::LegacySessionErrorCB& legacy_session_error_cb,
const media::SessionKeysChangeCB& session_keys_change_cb,
- const media::SessionExpirationUpdateCB& session_expiration_update_cb) {
- // TODO(jrummell): Pass |security_origin| to all constructors.
- // TODO(jrummell): Enable the following line once blink code updated to
- // check the security origin before calling.
- // DCHECK(security_origin.is_valid());
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb,
+ const media::CdmCreatedCB& cdm_created_cb) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!security_origin.is_valid()) {
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE, base::Bind(cdm_created_cb, nullptr, "Invalid origin."));
+ return;
+ }
- if (CanUseAesDecryptor(key_system)) {
- return scoped_ptr<media::MediaKeys>(new media::AesDecryptor(
- session_message_cb, session_closed_cb, session_keys_change_cb));
+ if (media::CanUseAesDecryptor(key_system)) {
+ // TODO(sandersd): Currently the prefixed API always allows distinctive
+ // identifiers and persistent state. Once that changes we can sanity check
+ // here that neither is allowed for AesDecryptor, since it does not support
+ // them and should never be configured that way. http://crbug.com/455271
+ scoped_ptr<media::MediaKeys> cdm(
+ new media::AesDecryptor(security_origin, session_message_cb,
+ session_closed_cb, session_keys_change_cb));
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE, base::Bind(cdm_created_cb, base::Passed(&cdm), ""));
+ return;
}
#if defined(ENABLE_PEPPER_CDMS)
- return scoped_ptr<media::MediaKeys>(
- PpapiDecryptor::Create(key_system,
- security_origin,
- create_pepper_cdm_cb_,
- session_message_cb,
- session_ready_cb,
- session_closed_cb,
- session_error_cb,
- session_keys_change_cb,
- session_expiration_update_cb));
+ DCHECK(!cdm_config.use_hw_secure_codecs);
+ PpapiDecryptor::Create(
+ key_system, security_origin, cdm_config.allow_distinctive_identifier,
+ cdm_config.allow_persistent_state, create_pepper_cdm_cb_,
+ session_message_cb, session_closed_cb, legacy_session_error_cb,
+ session_keys_change_cb, session_expiration_update_cb, cdm_created_cb);
#elif defined(ENABLE_BROWSER_CDMS)
- return scoped_ptr<media::MediaKeys>(
- ProxyMediaKeys::Create(key_system,
- security_origin,
- manager_,
- session_message_cb,
- session_ready_cb,
- session_closed_cb,
- session_error_cb,
- session_keys_change_cb,
- session_expiration_update_cb));
+ DCHECK(cdm_config.allow_distinctive_identifier);
+ DCHECK(cdm_config.allow_persistent_state);
+ ProxyMediaKeys::Create(
+ key_system, security_origin, cdm_config.use_hw_secure_codecs, manager_,
+ session_message_cb, session_closed_cb, legacy_session_error_cb,
+ session_keys_change_cb, session_expiration_update_cb, cdm_created_cb);
#else
- return nullptr;
+ // No possible CDM to create, so fail the request.
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE,
+ base::Bind(cdm_created_cb, nullptr, "Key system not supported."));
#endif // defined(ENABLE_PEPPER_CDMS)
}
diff --git a/chromium/content/renderer/media/crypto/render_cdm_factory.h b/chromium/content/renderer/media/crypto/render_cdm_factory.h
index f09f01bf433..80502db9332 100644
--- a/chromium/content/renderer/media/crypto/render_cdm_factory.h
+++ b/chromium/content/renderer/media/crypto/render_cdm_factory.h
@@ -8,6 +8,8 @@
#include <string>
#include "base/memory/scoped_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "content/public/renderer/render_frame_observer.h"
#include "media/base/cdm_factory.h"
#include "media/base/media_keys.h"
@@ -17,34 +19,41 @@
class GURL;
+namespace media {
+struct CdmConfig;
+} // namespace media
+
namespace content {
#if defined(ENABLE_BROWSER_CDMS)
class RendererCdmManager;
#endif
-class RenderCdmFactory : public media::CdmFactory {
+// CdmFactory implementation in content/renderer. This class is not thread safe
+// and should only be used on one thread.
+class RenderCdmFactory : public media::CdmFactory, public RenderFrameObserver {
public:
+ RenderCdmFactory(
#if defined(ENABLE_PEPPER_CDMS)
- explicit RenderCdmFactory(const CreatePepperCdmCB& create_pepper_cdm_cb);
+ const CreatePepperCdmCB& create_pepper_cdm_cb,
#elif defined(ENABLE_BROWSER_CDMS)
- explicit RenderCdmFactory(RendererCdmManager* manager);
-#else
- RenderCdmFactory();
+ RendererCdmManager* manager,
#endif // defined(ENABLE_PEPPER_CDMS)
+ RenderFrame* render_frame);
~RenderCdmFactory() override;
- scoped_ptr<media::MediaKeys> Create(
+ // CdmFactory implementation.
+ void Create(
const std::string& key_system,
const GURL& security_origin,
+ const media::CdmConfig& cdm_config,
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 media::LegacySessionErrorCB& legacy_session_error_cb,
const media::SessionKeysChangeCB& session_keys_change_cb,
- const media::SessionExpirationUpdateCB& session_expiration_update_cb)
- override;
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb,
+ const media::CdmCreatedCB& cdm_created_cb) override;
private:
#if defined(ENABLE_PEPPER_CDMS)
@@ -54,6 +63,8 @@ class RenderCdmFactory : public media::CdmFactory {
RendererCdmManager* manager_;
#endif
+ base::ThreadChecker thread_checker_;
+
DISALLOW_COPY_AND_ASSIGN(RenderCdmFactory);
};
diff --git a/chromium/content/renderer/media/crypto/renderer_cdm_manager.cc b/chromium/content/renderer/media/crypto/renderer_cdm_manager.cc
index 3bfdc6e0709..be9c5eaade7 100644
--- a/chromium/content/renderer/media/crypto/renderer_cdm_manager.cc
+++ b/chromium/content/renderer/media/crypto/renderer_cdm_manager.cc
@@ -7,18 +7,21 @@
#include "base/stl_util.h"
#include "content/common/media/cdm_messages.h"
#include "content/renderer/media/crypto/proxy_media_keys.h"
+#include "media/base/cdm_context.h"
+#include "media/base/limits.h"
namespace content {
+using media::MediaKeys;
+
// Maximum sizes for various EME API parameters. These are checks to prevent
// unnecessarily large messages from being passed around, and the sizes
// are somewhat arbitrary as the EME spec doesn't specify any limits.
-const size_t kMaxWebSessionIdLength = 512;
const size_t kMaxSessionMessageLength = 10240; // 10 KB
RendererCdmManager::RendererCdmManager(RenderFrame* render_frame)
: RenderFrameObserver(render_frame),
- next_cdm_id_(media::MediaKeys::kInvalidCdmId + 1) {
+ next_cdm_id_(media::CdmContext::kInvalidCdmId + 1) {
}
RendererCdmManager::~RendererCdmManager() {
@@ -30,46 +33,69 @@ RendererCdmManager::~RendererCdmManager() {
bool RendererCdmManager::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RendererCdmManager, msg)
- IPC_MESSAGE_HANDLER(CdmMsg_SessionCreated, OnSessionCreated)
IPC_MESSAGE_HANDLER(CdmMsg_SessionMessage, OnSessionMessage)
- IPC_MESSAGE_HANDLER(CdmMsg_SessionReady, OnSessionReady)
IPC_MESSAGE_HANDLER(CdmMsg_SessionClosed, OnSessionClosed)
- IPC_MESSAGE_HANDLER(CdmMsg_SessionError, OnSessionError)
+ IPC_MESSAGE_HANDLER(CdmMsg_LegacySessionError, OnLegacySessionError)
+ IPC_MESSAGE_HANDLER(CdmMsg_SessionKeysChange, OnSessionKeysChange)
+ IPC_MESSAGE_HANDLER(CdmMsg_SessionExpirationUpdate,
+ OnSessionExpirationUpdate)
+ IPC_MESSAGE_HANDLER(CdmMsg_ResolvePromise, OnPromiseResolved)
+ IPC_MESSAGE_HANDLER(CdmMsg_ResolvePromiseWithSession,
+ OnPromiseResolvedWithSession)
+ IPC_MESSAGE_HANDLER(CdmMsg_RejectPromise, OnPromiseRejected)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void RendererCdmManager::InitializeCdm(int cdm_id,
+ uint32_t promise_id,
ProxyMediaKeys* media_keys,
const std::string& key_system,
- const GURL& security_origin) {
+ const GURL& security_origin,
+ bool use_hw_secure_codecs) {
+ DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
+ CdmHostMsg_InitializeCdm_Params params;
+ params.key_system = key_system;
+ params.security_origin = security_origin;
+ params.use_hw_secure_codecs = use_hw_secure_codecs;
+ Send(new CdmHostMsg_InitializeCdm(routing_id(), cdm_id, promise_id, params));
+}
+
+void RendererCdmManager::SetServerCertificate(
+ int cdm_id,
+ uint32_t promise_id,
+ const std::vector<uint8_t>& certificate) {
DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
- Send(new CdmHostMsg_InitializeCdm(
- routing_id(), cdm_id, key_system, security_origin));
+ Send(new CdmHostMsg_SetServerCertificate(routing_id(), cdm_id, promise_id,
+ certificate));
}
-void RendererCdmManager::CreateSession(
+void RendererCdmManager::CreateSessionAndGenerateRequest(
int cdm_id,
- uint32 session_id,
- CdmHostMsg_CreateSession_ContentType content_type,
- const std::vector<uint8>& init_data) {
+ uint32_t promise_id,
+ CdmHostMsg_CreateSession_InitDataType init_data_type,
+ const std::vector<uint8_t>& init_data) {
DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
- Send(new CdmHostMsg_CreateSession(
- routing_id(), cdm_id, session_id, content_type, init_data));
+ Send(new CdmHostMsg_CreateSessionAndGenerateRequest(
+ routing_id(), cdm_id, promise_id, init_data_type, init_data));
}
void RendererCdmManager::UpdateSession(int cdm_id,
- uint32 session_id,
- const std::vector<uint8>& response) {
+ uint32_t promise_id,
+ const std::string& session_id,
+ const std::vector<uint8_t>& response) {
DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
- Send(
- new CdmHostMsg_UpdateSession(routing_id(), cdm_id, session_id, response));
+ Send(new CdmHostMsg_UpdateSession(routing_id(), cdm_id, promise_id,
+ session_id, response));
}
-void RendererCdmManager::ReleaseSession(int cdm_id, uint32 session_id) {
+void RendererCdmManager::CloseSession(int cdm_id,
+ uint32_t promise_id,
+ const std::string& session_id) {
DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered.";
- Send(new CdmHostMsg_ReleaseSession(routing_id(), cdm_id, session_id));
+ Send(new CdmHostMsg_CloseSession(routing_id(), cdm_id, promise_id,
+ session_id));
}
void RendererCdmManager::DestroyCdm(int cdm_id) {
@@ -77,57 +103,106 @@ void RendererCdmManager::DestroyCdm(int cdm_id) {
Send(new CdmHostMsg_DestroyCdm(routing_id(), cdm_id));
}
-void RendererCdmManager::OnSessionCreated(int cdm_id,
- uint32 session_id,
- const std::string& web_session_id) {
- if (web_session_id.length() > kMaxWebSessionIdLength) {
- OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
+void RendererCdmManager::OnSessionMessage(
+ int cdm_id,
+ const std::string& session_id,
+ media::MediaKeys::MessageType message_type,
+ const std::vector<uint8>& message,
+ const GURL& legacy_destination_url) {
+ if (message.size() > kMaxSessionMessageLength) {
+ NOTREACHED();
+ LOG(ERROR) << "Message is too long and dropped.";
return;
}
ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
if (media_keys)
- media_keys->OnSessionCreated(session_id, web_session_id);
+ media_keys->OnSessionMessage(session_id, message_type, message,
+ legacy_destination_url);
}
-void RendererCdmManager::OnSessionMessage(int cdm_id,
- uint32 session_id,
- const std::vector<uint8>& message,
- const GURL& destination_url) {
- if (message.size() > kMaxSessionMessageLength) {
- OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
+void RendererCdmManager::OnSessionClosed(int cdm_id,
+ const std::string& session_id) {
+ ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
+ if (media_keys)
+ media_keys->OnSessionClosed(session_id);
+}
+
+void RendererCdmManager::OnLegacySessionError(
+ int cdm_id,
+ const std::string& session_id,
+ MediaKeys::Exception exception,
+ uint32 system_code,
+ const std::string& error_message) {
+ ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
+ if (media_keys)
+ media_keys->OnLegacySessionError(session_id, exception, system_code,
+ error_message);
+}
+
+void RendererCdmManager::OnSessionKeysChange(
+ int cdm_id,
+ const std::string& session_id,
+ bool has_additional_usable_key,
+ const std::vector<media::CdmKeyInformation>& key_info_vector) {
+ ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
+ if (!media_keys)
return;
- }
+ media::CdmKeysInfo keys_info;
+ keys_info.reserve(key_info_vector.size());
+ for (const auto& key_info : key_info_vector)
+ keys_info.push_back(new media::CdmKeyInformation(key_info));
+
+ media_keys->OnSessionKeysChange(session_id, has_additional_usable_key,
+ keys_info.Pass());
+}
+
+void RendererCdmManager::OnSessionExpirationUpdate(
+ int cdm_id,
+ const std::string& session_id,
+ const base::Time& new_expiry_time) {
ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
if (media_keys)
- media_keys->OnSessionMessage(session_id, message, destination_url);
+ media_keys->OnSessionExpirationUpdate(session_id, new_expiry_time);
}
-void RendererCdmManager::OnSessionReady(int cdm_id, uint32 session_id) {
+void RendererCdmManager::OnPromiseResolved(int cdm_id, uint32_t promise_id) {
ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
if (media_keys)
- media_keys->OnSessionReady(session_id);
+ media_keys->OnPromiseResolved(promise_id);
}
-void RendererCdmManager::OnSessionClosed(int cdm_id, uint32 session_id) {
+void RendererCdmManager::OnPromiseResolvedWithSession(
+ int cdm_id,
+ uint32_t promise_id,
+ const std::string& session_id) {
+ if (session_id.length() > media::limits::kMaxSessionIdLength) {
+ NOTREACHED();
+ OnPromiseRejected(cdm_id, promise_id, MediaKeys::INVALID_ACCESS_ERROR, 0,
+ "Session ID is too long");
+ return;
+ }
+
ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
if (media_keys)
- media_keys->OnSessionClosed(session_id);
+ media_keys->OnPromiseResolvedWithSession(promise_id, session_id);
}
-void RendererCdmManager::OnSessionError(int cdm_id,
- uint32 session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code) {
+void RendererCdmManager::OnPromiseRejected(int cdm_id,
+ uint32_t promise_id,
+ MediaKeys::Exception exception,
+ uint32_t system_code,
+ const std::string& error_message) {
ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id);
if (media_keys)
- media_keys->OnSessionError(session_id, error_code, system_code);
+ media_keys->OnPromiseRejected(promise_id, exception, system_code,
+ error_message);
}
int RendererCdmManager::RegisterMediaKeys(ProxyMediaKeys* media_keys) {
int cdm_id = next_cdm_id_++;
- DCHECK_NE(cdm_id, media::MediaKeys::kInvalidCdmId);
+ DCHECK_NE(cdm_id, media::CdmContext::kInvalidCdmId);
DCHECK(!ContainsKey(proxy_media_keys_map_, cdm_id));
proxy_media_keys_map_[cdm_id] = media_keys;
return cdm_id;
diff --git a/chromium/content/renderer/media/crypto/renderer_cdm_manager.h b/chromium/content/renderer/media/crypto/renderer_cdm_manager.h
index 4944144685d..1ab051324e6 100644
--- a/chromium/content/renderer/media/crypto/renderer_cdm_manager.h
+++ b/chromium/content/renderer/media/crypto/renderer_cdm_manager.h
@@ -28,24 +28,33 @@ class RendererCdmManager : public RenderFrameObserver {
public:
// Constructs a RendererCdmManager object for the |render_frame|.
explicit RendererCdmManager(RenderFrame* render_frame);
- virtual ~RendererCdmManager();
+ ~RendererCdmManager() override;
// RenderFrameObserver overrides.
- virtual bool OnMessageReceived(const IPC::Message& msg) override;
+ bool OnMessageReceived(const IPC::Message& msg) override;
// Encrypted media related methods.
void InitializeCdm(int cdm_id,
+ uint32_t promise_id,
ProxyMediaKeys* media_keys,
const std::string& key_system,
- const GURL& security_origin);
- void CreateSession(int cdm_id,
- uint32 session_id,
- CdmHostMsg_CreateSession_ContentType conent_type,
- const std::vector<uint8>& init_data);
+ const GURL& security_origin,
+ bool use_hw_secure_codecs);
+ void SetServerCertificate(int cdm_id,
+ uint32_t promise_id,
+ const std::vector<uint8>& certificate);
+ void CreateSessionAndGenerateRequest(
+ int cdm_id,
+ uint32_t promise_id,
+ CdmHostMsg_CreateSession_InitDataType init_data_type,
+ const std::vector<uint8>& init_data);
void UpdateSession(int cdm_id,
- uint32 session_id,
+ uint32_t promise_id,
+ const std::string& session_id,
const std::vector<uint8>& response);
- void ReleaseSession(int cdm_id, uint32 session_id);
+ void CloseSession(int cdm_id,
+ uint32_t promise_id,
+ const std::string& session_id);
void DestroyCdm(int cdm_id);
// Registers a ProxyMediaKeys object. Returns allocated CDM ID.
@@ -59,19 +68,35 @@ class RendererCdmManager : public RenderFrameObserver {
ProxyMediaKeys* GetMediaKeys(int cdm_id);
// Message handlers.
- void OnSessionCreated(int cdm_id,
- uint32 session_id,
- const std::string& web_session_id);
void OnSessionMessage(int cdm_id,
- uint32 session_id,
+ const std::string& session_id,
+ media::MediaKeys::MessageType message_type,
const std::vector<uint8>& message,
- const GURL& destination_url);
- void OnSessionReady(int cdm_id, uint32 session_id);
- void OnSessionClosed(int cdm_id, uint32 session_id);
- void OnSessionError(int cdm_id,
- uint32 session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code);
+ const GURL& legacy_destination_url);
+ void OnSessionClosed(int cdm_id, const std::string& session_id);
+ void OnLegacySessionError(int cdm_id,
+ const std::string& session_id,
+ media::MediaKeys::Exception exception,
+ uint32 system_code,
+ const std::string& error_message);
+ void OnSessionKeysChange(
+ int cdm_id,
+ const std::string& session_id,
+ bool has_additional_usable_key,
+ const std::vector<media::CdmKeyInformation>& key_info_vector);
+ void OnSessionExpirationUpdate(int cdm_id,
+ const std::string& session_id,
+ const base::Time& new_expiry_time);
+
+ void OnPromiseResolved(int cdm_id, uint32_t promise_id);
+ void OnPromiseResolvedWithSession(int cdm_id,
+ uint32_t promise_id,
+ const std::string& session_id);
+ void OnPromiseRejected(int cdm_id,
+ uint32_t promise_id,
+ media::MediaKeys::Exception exception,
+ uint32_t system_code,
+ const std::string& error_message);
// CDM ID should be unique per renderer frame.
// TODO(xhwang): Use uint32 to prevent undefined overflow behavior.