diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-22 20:31:35 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-22 20:31:35 +0000 |
commit | ab998e8762a5aeab7b9bbb0127115abb66ffd4f2 (patch) | |
tree | f4eadfcde4e1075c3dad8c45148a140db5f4e047 | |
parent | ff269fb5d318641d50333875028b8e49fda8bfaf (diff) | |
download | chromium_src-ab998e8762a5aeab7b9bbb0127115abb66ffd4f2.zip chromium_src-ab998e8762a5aeab7b9bbb0127115abb66ffd4f2.tar.gz chromium_src-ab998e8762a5aeab7b9bbb0127115abb66ffd4f2.tar.bz2 |
Add decrypt-only external clear key browser tests.
These tests cover the code path where a CDM is used in decrypt-only mode.
BUG=321420
TEST=none
Review URL: https://codereview.chromium.org/79903002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236818 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/media/encrypted_media_browsertest.cc | 40 | ||||
-rw-r--r-- | chrome/renderer/media/chrome_key_systems.cc | 10 | ||||
-rw-r--r-- | chrome/test/data/media/encrypted_media_utils.js | 11 | ||||
-rw-r--r-- | media/cdm/key_system_names.cc | 14 | ||||
-rw-r--r-- | media/cdm/key_system_names.h | 4 | ||||
-rw-r--r-- | media/cdm/ppapi/clear_key_cdm.cc | 28 | ||||
-rw-r--r-- | media/cdm/ppapi/clear_key_cdm.h | 4 |
7 files changed, 83 insertions, 28 deletions
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 1998c93..6f52d2b 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc @@ -33,8 +33,11 @@ const char kClearKeyCdmPluginMimeType[] = "application/x-ppapi-clearkey-cdm"; // Available key systems. const char kClearKeyKeySystem[] = "webkit-org.w3.clearkey"; -const char kExternalClearKeyKeySystem[] = - "org.chromium.externalclearkey"; +const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"; +const char kExternalClearKeyDecryptOnlyKeySystem[] = + "org.chromium.externalclearkey.decryptonly"; +const char kExternalClearKeyInitializeFailKeySystem[] = + "org.chromium.externalclearkey.initializefail"; // Supported media types. const char kWebMAudioOnly[] = "audio/webm; codecs=\"vorbis\""; @@ -66,18 +69,25 @@ static bool IsMSESupported() { return true; } +static bool IsParentKeySystemOf(const std::string& parent_key_system, + const std::string& key_system) { + std::string prefix = parent_key_system + '.'; + return key_system.substr(0, prefix.size()) == prefix; +} + // Base class for encrypted media tests. class EncryptedMediaTestBase : public MediaBrowserTest { public: EncryptedMediaTestBase() : is_pepper_cdm_registered_(false) {} - bool IsExternalClearKey(const char* key_system) { - return (strcmp(key_system, kExternalClearKeyKeySystem) == 0); + bool IsExternalClearKey(const std::string& key_system) { + return key_system == kExternalClearKeyKeySystem || + IsParentKeySystemOf(kExternalClearKeyKeySystem, key_system); } #if defined(WIDEVINE_CDM_AVAILABLE) - bool IsWidevine(const char* key_system) { - return (strcmp(key_system, kWidevineKeySystem) == 0); + bool IsWidevine(const std::string& key_system) { + return key_system == kWidevineKeySystem; } #endif // defined(WIDEVINE_CDM_AVAILABLE) @@ -148,13 +158,11 @@ class EncryptedMediaTestBase : public MediaBrowserTest { CommandLine* command_line) { #if defined(ENABLE_PEPPER_CDMS) if (IsExternalClearKey(key_system)) { - RegisterPepperCdm(command_line, kClearKeyCdmAdapterFileName, - kExternalClearKeyKeySystem); + RegisterPepperCdm(command_line, kClearKeyCdmAdapterFileName, key_system); } #if defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) else if (IsWidevine(key_system)) { - RegisterPepperCdm(command_line, kWidevineCdmAdapterFileName, - kWidevineKeySystem); + RegisterPepperCdm(command_line, kWidevineCdmAdapterFileName, key_system); } #endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(WIDEVINE_CDM_IS_COMPONENT) #endif // defined(ENABLE_PEPPER_CDMS) @@ -187,10 +195,10 @@ class EncryptedMediaTestBase : public MediaBrowserTest { // Adapted from key_systems.cc. std::string GetPepperType(const std::string& key_system) { - if (key_system == kExternalClearKeyKeySystem) + if (IsExternalClearKey(key_system)) return kClearKeyCdmPluginMimeType; #if defined(WIDEVINE_CDM_AVAILABLE) - if (key_system == kWidevineKeySystem) + if (IsWidevine(key_system)) return kWidevineCdmPluginMimeType; #endif // WIDEVINE_CDM_AVAILABLE @@ -203,7 +211,8 @@ class EncryptedMediaTestBase : public MediaBrowserTest { }; #if defined(ENABLE_PEPPER_CDMS) -// Tests encrypted media playback using ExternalClearKey key system. +// Tests encrypted media playback using ExternalClearKey key system in +// decrypt-and-decode mode. class ECKEncryptedMediaTest : public EncryptedMediaTestBase { protected: virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { @@ -300,6 +309,9 @@ INSTANTIATE_TEST_CASE_P(SRC_ExternalClearKey, EncryptedMediaTest, Combine(Values(kExternalClearKeyKeySystem), Values(SRC))); INSTANTIATE_TEST_CASE_P(MSE_ExternalClearKey, EncryptedMediaTest, Combine(Values(kExternalClearKeyKeySystem), Values(MSE))); +// To reduce test time, only run ExternalClearKeyDecryptOnly with MSE. +INSTANTIATE_TEST_CASE_P(MSE_ExternalClearKeyDecryptOnly, EncryptedMediaTest, + Combine(Values(kExternalClearKeyDecryptOnlyKeySystem), Values(MSE))); #endif // defined(ENABLE_PEPPER_CDMS) #if defined(WIDEVINE_CDM_AVAILABLE) @@ -381,7 +393,7 @@ IN_PROC_BROWSER_TEST_F(ECKEncryptedMediaTest, RunEncryptedMediaTest("encrypted_media_player.html", "bear-a-enc_a.webm", kWebMAudioOnly, - "org.chromium.externalclearkey.initializefail", + kExternalClearKeyInitializeFailKeySystem, SRC, kEmeKeyError); } diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc index 0372a80..0af0a1a 100644 --- a/chrome/renderer/media/chrome_key_systems.cc +++ b/chrome/renderer/media/chrome_key_systems.cc @@ -64,6 +64,10 @@ static void AddExternalClearKey( std::vector<KeySystemInfo>* concrete_key_systems) { static const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"; + static const char kExternalClearKeyDecryptOnlyKeySystem[] = + "org.chromium.externalclearkey.decryptonly"; + static const char kExternalClearKeyInitializeFailKeySystem[] = + "org.chromium.externalclearkey.initializefail"; static const char kExternalClearKeyPepperType[] = "application/x-ppapi-clearkey-cdm"; @@ -90,7 +94,11 @@ static void AddExternalClearKey( // A key system that Chrome thinks is supported by ClearKeyCdm, but actually // will be refused by ClearKeyCdm. This is to test the CDM initialization // failure case. - info.key_system += ".initializefail"; + info.key_system = kExternalClearKeyInitializeFailKeySystem; + concrete_key_systems->push_back(info); + + // Add support of decrypt-only mode in ClearKeyCdm. + info.key_system = kExternalClearKeyDecryptOnlyKeySystem; concrete_key_systems->push_back(info); } #endif // defined(ENABLE_PEPPER_CDMS) diff --git a/chrome/test/data/media/encrypted_media_utils.js b/chrome/test/data/media/encrypted_media_utils.js index b7fece4..3486197 100644 --- a/chrome/test/data/media/encrypted_media_utils.js +++ b/chrome/test/data/media/encrypted_media_utils.js @@ -104,8 +104,17 @@ function loadEncryptedMedia(video, mediaFile, keySystem, key, useMSE, } function verifyHeartbeatMessage(e) { + String.prototype.startsWith = function(prefix) { + return this.indexOf(prefix) === 0; + } + + function isExternalClearKey(keySystem) { + return keySystem == EXTERNAL_CLEAR_KEY_KEY_SYSTEM || + keySystem.startsWith(EXTERNAL_CLEAR_KEY_KEY_SYSTEM + '.'); + } + // Only External Clear Key sends a HEARTBEAT message. - if (e.keySystem != EXTERNAL_CLEAR_KEY_KEY_SYSTEM) { + if (!isExternalClearKey(e.keySystem)) { failTest('Unexpected heartbeat from ' + e.keySystem); return; } diff --git a/media/cdm/key_system_names.cc b/media/cdm/key_system_names.cc index 97cc9e8..b9eceb2 100644 --- a/media/cdm/key_system_names.cc +++ b/media/cdm/key_system_names.cc @@ -4,10 +4,24 @@ #include "media/cdm/key_system_names.h" +#include <string> + namespace media { const char kPrefixedClearKey[] = "webkit-org.w3.clearkey"; const char kUnprefixedClearKey[] = "org.w3.clearkey"; const char kExternalClearKey[] = "org.chromium.externalclearkey"; +static bool IsParentKeySystemOf(const std::string& parent_key_system, + const std::string& key_system) { + std::string prefix = parent_key_system + '.'; + return key_system.substr(0, prefix.size()) == prefix; +} + + +bool IsExternalClearKey(const std::string& key_system) { + return key_system == kExternalClearKey || + IsParentKeySystemOf(kExternalClearKey, key_system); +} + } // namespace media diff --git a/media/cdm/key_system_names.h b/media/cdm/key_system_names.h index 0216c69..1b26869 100644 --- a/media/cdm/key_system_names.h +++ b/media/cdm/key_system_names.h @@ -26,9 +26,7 @@ MEDIA_EXPORT inline bool IsClearKey(const std::string& key_system) { } // Returns true if |key_system| is External Clear Key, false otherwise. -MEDIA_EXPORT inline bool IsExternalClearKey(const std::string& key_system) { - return key_system == kExternalClearKey; -} +MEDIA_EXPORT bool IsExternalClearKey(const std::string& key_system); } // namespace media diff --git a/media/cdm/ppapi/clear_key_cdm.cc b/media/cdm/ppapi/clear_key_cdm.cc index 3728eff..044cbb2 100644 --- a/media/cdm/ppapi/clear_key_cdm.cc +++ b/media/cdm/ppapi/clear_key_cdm.cc @@ -61,6 +61,8 @@ static bool g_ffmpeg_lib_initialized = InitializeFFmpegLibraries(); const char kClearKeyCdmVersion[] = "0.1.0.1"; const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"; +const char kExternalClearKeyDecryptOnlyKeySystem[] = + "org.chromium.externalclearkey.decryptonly"; const int64 kSecondsPerMinute = 60; const int64 kMsPerSecond = 1000; const int64 kInitialTimerDelayMs = 200; @@ -125,14 +127,16 @@ void INITIALIZE_CDM_MODULE() { void DeinitializeCdmModule() { } -void* CreateCdmInstance( - int cdm_interface_version, - const char* key_system, uint32_t key_system_size, - GetCdmHostFunc get_cdm_host_func, void* user_data) { +void* CreateCdmInstance(int cdm_interface_version, + const char* key_system, uint32_t key_system_size, + GetCdmHostFunc get_cdm_host_func, + void* user_data) { DVLOG(1) << "CreateCdmInstance()"; - if (std::string(key_system, key_system_size) != kExternalClearKeyKeySystem) { - DVLOG(1) << "Unsupported key system."; + std::string key_system_string(key_system, key_system_size); + if (key_system_string != kExternalClearKeyKeySystem && + key_system_string != kExternalClearKeyDecryptOnlyKeySystem) { + DVLOG(1) << "Unsupported key system:" << key_system_string; return NULL; } @@ -144,7 +148,8 @@ void* CreateCdmInstance( if (!host) return NULL; - return new media::ClearKeyCdm(host); + return new media::ClearKeyCdm( + host, key_system_string == kExternalClearKeyDecryptOnlyKeySystem); } const char* GetCdmVersion() { @@ -198,12 +203,13 @@ void ClearKeyCdm::Client::SetSessionId(uint32 reference_id, session_id_ = session_id; } -ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host) +ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, bool is_decrypt_only) : decryptor_(base::Bind(&Client::KeyAdded, base::Unretained(&client_)), base::Bind(&Client::KeyError, base::Unretained(&client_)), base::Bind(&Client::KeyMessage, base::Unretained(&client_)), base::Bind(&Client::SetSessionId, base::Unretained(&client_))), host_(host), + is_decrypt_only_(is_decrypt_only), timer_delay_ms_(kInitialTimerDelayMs), timer_set_(false) { #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) @@ -352,6 +358,9 @@ cdm::Status ClearKeyCdm::Decrypt( cdm::Status ClearKeyCdm::InitializeAudioDecoder( const cdm::AudioDecoderConfig& audio_decoder_config) { + if (is_decrypt_only_) + return cdm::kSessionError; + #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) if (!audio_decoder_) audio_decoder_.reset(new media::FFmpegCdmAudioDecoder(host_)); @@ -373,6 +382,9 @@ cdm::Status ClearKeyCdm::InitializeAudioDecoder( cdm::Status ClearKeyCdm::InitializeVideoDecoder( const cdm::VideoDecoderConfig& video_decoder_config) { + if (is_decrypt_only_) + return cdm::kSessionError; + if (video_decoder_ && video_decoder_->is_initialized()) { DCHECK(!video_decoder_->is_initialized()); return cdm::kSessionError; diff --git a/media/cdm/ppapi/clear_key_cdm.h b/media/cdm/ppapi/clear_key_cdm.h index c8d0703..6ef4e04 100644 --- a/media/cdm/ppapi/clear_key_cdm.h +++ b/media/cdm/ppapi/clear_key_cdm.h @@ -30,7 +30,7 @@ class FFmpegCdmAudioDecoder; // Clear key implementation of the cdm::ContentDecryptionModule interface. class ClearKeyCdm : public ClearKeyCdmInterface { public: - explicit ClearKeyCdm(Host* host); + explicit ClearKeyCdm(Host* host, bool is_decrypt_only); virtual ~ClearKeyCdm(); // ContentDecryptionModule implementation. @@ -150,6 +150,8 @@ class ClearKeyCdm : public ClearKeyCdmInterface { ClearKeyCdmHost* host_; + const bool is_decrypt_only_; + std::string heartbeat_session_id_; std::string next_heartbeat_message_; |