diff options
| author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-14 21:22:05 +0000 |
|---|---|---|
| committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-14 21:22:05 +0000 |
| commit | a941d4e57a9c663e2c9feb3779fef16f8f3f7457 (patch) | |
| tree | 943ddcf1cce5dfa16131ce1bead16b0955895c38 | |
| parent | b6b41cca31a6742abf132d4175befa81d359c639 (diff) | |
| download | chromium_src-a941d4e57a9c663e2c9feb3779fef16f8f3f7457.zip chromium_src-a941d4e57a9c663e2c9feb3779fef16f8f3f7457.tar.gz chromium_src-a941d4e57a9c663e2c9feb3779fef16f8f3f7457.tar.bz2 | |
Handle CdmWrapper::Initialize() failure gracefully.
Since CdmWrapper::Initialize() doesn't report error, GenerateKeyRequest() et al
can be called even if Initialize() failed previously.
For MediaKeys calls, we should fire KeyError when they are called without valid
|cdm_|. For Decryptor calls, we should fire the callback with error code.
Also added EncryptedMediaTest.ExternalClearKeyInitializeCDMFail test to cover
this case. Chrome will claim that the ClearKey CDM supports key system
"org.chromium.externalclearkey.fail". But actually ClearKey CDM will return NULL
for this key system in CreateCdmInstance();
BUG=306241,179570
TEST=Unit tests added.
Review URL: https://codereview.chromium.org/27030007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228528 0039d316-1c4b-4281-b951-d872f2087c98
| -rw-r--r-- | chrome/browser/media/encrypted_media_browsertest.cc | 11 | ||||
| -rw-r--r-- | chrome/renderer/media/chrome_key_systems.cc | 7 | ||||
| -rw-r--r-- | media/cdm/ppapi/cdm_wrapper.cc | 41 | ||||
| -rw-r--r-- | media/cdm/ppapi/clear_key_cdm.cc | 6 |
4 files changed, 43 insertions, 22 deletions
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc index 850d16c..e1e68aa 100644 --- a/chrome/browser/media/encrypted_media_browsertest.cc +++ b/chrome/browser/media/encrypted_media_browsertest.cc @@ -306,3 +306,14 @@ IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, WVParentThrowsException) { kWebMAudioOnly, "com.widevine", SRC, kEmeGkrException); } #endif // defined(WIDEVINE_CDM_AVAILABLE) + +#if defined(ENABLE_PEPPER_CDMS) +IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, ExternalClearKeyInitializeCDMFail) { + RunEncryptedMediaTest("encrypted_media_player.html", + "bear-a-enc_a.webm", + kWebMAudioOnly, + "org.chromium.externalclearkey.initializefail", + SRC, + kEmeKeyError); +} +#endif // defined(ENABLE_PEPPER_CDMS) diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc index 014035d..12dfa92 100644 --- a/chrome/renderer/media/chrome_key_systems.cc +++ b/chrome/renderer/media/chrome_key_systems.cc @@ -69,10 +69,15 @@ static void AddExternalClearKey( info.supported_types.push_back(std::make_pair(kAudioMp4, kMp4a)); info.supported_types.push_back(std::make_pair(kVideoMp4, kMp4aAvc1)); #endif // defined(USE_PROPRIETARY_CODECS) - info.pepper_type = kExternalClearKeyPepperType; concrete_key_systems->push_back(info); + + // 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"; + concrete_key_systems->push_back(info); } #endif // defined(ENABLE_PEPPER_CDMS) diff --git a/media/cdm/ppapi/cdm_wrapper.cc b/media/cdm/ppapi/cdm_wrapper.cc index 6d8a788..60a8e44 100644 --- a/media/cdm/ppapi/cdm_wrapper.cc +++ b/media/cdm/ppapi/cdm_wrapper.cc @@ -586,6 +586,7 @@ class CdmWrapper : public pp::Instance, void SendKeyAdded(const std::string& key_system, const std::string& session_id); + // TODO(jrummell): Drop the |key_system| parameter. void SendKeyErrorInternal(const std::string& key_system, const std::string& session_id, cdm::MediaKeyError error_code, @@ -707,25 +708,29 @@ bool CdmWrapper::CreateCdmInstance(const std::string& key_system) { return (cdm_ != NULL); } +// No KeyErrors should be reported in this function because they cannot be +// bubbled up in the WD EME API. Those errors will be reported during session +// creation (aka GenerateKeyRequest). void CdmWrapper::Initialize(const std::string& key_system, bool can_challenge_platform) { PP_DCHECK(!key_system.empty()); PP_DCHECK(key_system_.empty() || (key_system_ == key_system && cdm_)); - if (!cdm_) { - if (!CreateCdmInstance(key_system)) { - // TODO(jrummell): Is UnknownKeyError the correct response? - SendUnknownKeyError(key_system, std::string()); - return; - } - } + if (!cdm_ && !CreateCdmInstance(key_system)) + return; + PP_DCHECK(cdm_); key_system_ = key_system; } void CdmWrapper::GenerateKeyRequest(const std::string& type, pp::VarArrayBuffer init_data) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. + // Initialize() doesn't report an error, so GenerateKeyRequest() can be called + // even if Initialize() failed. + if (!cdm_) { + SendUnknownKeyError(key_system_, std::string()); + return; + } #if defined(CHECK_DOCUMENT_URL) PP_URLComponents_Dev url_components = {}; @@ -749,7 +754,8 @@ void CdmWrapper::GenerateKeyRequest(const std::string& type, void CdmWrapper::AddKey(const std::string& session_id, pp::VarArrayBuffer key, pp::VarArrayBuffer init_data) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. + // TODO(jrummell): In EME WD, AddKey() can only be called on valid sessions. + // We should be able to DCHECK(cdm_) when addressing http://crbug.com/249976. if (!cdm_) { SendUnknownKeyError(key_system_, session_id); return; @@ -779,7 +785,8 @@ void CdmWrapper::AddKey(const std::string& session_id, } void CdmWrapper::CancelKeyRequest(const std::string& session_id) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. + // TODO(jrummell): In EME WD, AddKey() can only be called on valid sessions. + // We should be able to DCHECK(cdm_) when addressing http://crbug.com/249976. if (!cdm_) { SendUnknownKeyError(key_system_, session_id); return; @@ -797,7 +804,6 @@ void CdmWrapper::CancelKeyRequest(const std::string& session_id) { void CdmWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer, const PP_EncryptedBlockInfo& encrypted_block_info) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. PP_DCHECK(!encrypted_buffer.is_null()); // Release a buffer that the caller indicated it is finished with. @@ -827,8 +833,6 @@ void CdmWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer, void CdmWrapper::InitializeAudioDecoder( const PP_AudioDecoderConfig& decoder_config, pp::Buffer_Dev extra_data_buffer) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. - cdm::Status status = cdm::kSessionError; if (cdm_) { cdm::AudioDecoderConfig cdm_decoder_config; @@ -854,8 +858,6 @@ void CdmWrapper::InitializeAudioDecoder( void CdmWrapper::InitializeVideoDecoder( const PP_VideoDecoderConfig& decoder_config, pp::Buffer_Dev extra_data_buffer) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. - cdm::Status status = cdm::kSessionError; if (cdm_) { cdm::VideoDecoderConfig cdm_decoder_config; @@ -883,7 +885,7 @@ void CdmWrapper::InitializeVideoDecoder( void CdmWrapper::DeinitializeDecoder(PP_DecryptorStreamType decoder_type, uint32_t request_id) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. + PP_DCHECK(cdm_); // InitializeXxxxxDecoder should have succeeded. if (cdm_) { cdm_->DeinitializeDecoder( PpDecryptorStreamTypeToCdmStreamType(decoder_type)); @@ -897,7 +899,7 @@ void CdmWrapper::DeinitializeDecoder(PP_DecryptorStreamType decoder_type, void CdmWrapper::ResetDecoder(PP_DecryptorStreamType decoder_type, uint32_t request_id) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. + PP_DCHECK(cdm_); // InitializeXxxxxDecoder should have succeeded. if (cdm_) cdm_->ResetDecoder(PpDecryptorStreamTypeToCdmStreamType(decoder_type)); @@ -910,8 +912,7 @@ void CdmWrapper::DecryptAndDecode( PP_DecryptorStreamType decoder_type, pp::Buffer_Dev encrypted_buffer, const PP_EncryptedBlockInfo& encrypted_block_info) { - PP_DCHECK(cdm_); // Initialize() should have succeeded. - + PP_DCHECK(cdm_); // InitializeXxxxxDecoder should have succeeded. // Release a buffer that the caller indicated it is finished with. allocator_.Release(encrypted_block_info.tracking_info.buffer_id); @@ -1027,7 +1028,6 @@ void CdmWrapper::SendKeyErrorInternal(const std::string& key_system, const std::string& session_id, cdm::MediaKeyError error_code, uint32_t system_code) { - PP_DCHECK(!key_system.empty()); PostOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError, SessionInfo(key_system_, session_id), error_code, @@ -1063,7 +1063,6 @@ void CdmWrapper::KeyError(int32_t result, cdm::MediaKeyError error_code, uint32_t system_code) { PP_DCHECK(result == PP_OK); - PP_DCHECK(!session_info.key_system.empty()); pp::ContentDecryptor_Private::KeyError( session_info.key_system, session_info.session_id, error_code, system_code); diff --git a/media/cdm/ppapi/clear_key_cdm.cc b/media/cdm/ppapi/clear_key_cdm.cc index d6702ca..6ab0773 100644 --- a/media/cdm/ppapi/clear_key_cdm.cc +++ b/media/cdm/ppapi/clear_key_cdm.cc @@ -60,6 +60,7 @@ static bool g_ffmpeg_lib_initialized = InitializeFFmpegLibraries(); #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER const char kClearKeyCdmVersion[] = "0.1.0.1"; +const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"; const int64 kSecondsPerMinute = 60; const int64 kMsPerSecond = 1000; const int64 kInitialTimerDelayMs = 200; @@ -130,6 +131,11 @@ void* CreateCdmInstance( 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."; + return NULL; + } + if (cdm_interface_version != cdm::kCdmInterfaceVersion) return NULL; |
