diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-16 01:27:36 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-16 01:27:36 +0000 |
commit | cbdc8c2b4b46c7e7886c9e99bc595a0b9936b381 (patch) | |
tree | fd03ab4a8636680c4c2dff01880751e25ef0cdca /webkit | |
parent | 46b7d64e85a9d8d28372d05b59b295dd6ecb0bc8 (diff) | |
download | chromium_src-cbdc8c2b4b46c7e7886c9e99bc595a0b9936b381.zip chromium_src-cbdc8c2b4b46c7e7886c9e99bc595a0b9936b381.tar.gz chromium_src-cbdc8c2b4b46c7e7886c9e99bc595a0b9936b381.tar.bz2 |
Generalize AesDecryptor to make it more spec compliant.
BUG=123260
TEST=media_unittests, encrypted-media layout tests.
Review URL: https://chromiumcodereview.appspot.com/10534096
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142553 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/media/webmediaplayer_impl.cc | 118 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_impl.h | 19 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_proxy.cc | 77 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_proxy.h | 53 |
4 files changed, 186 insertions, 81 deletions
diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc index bc7631d..588801c 100644 --- a/webkit/media/webmediaplayer_impl.cc +++ b/webkit/media/webmediaplayer_impl.cc @@ -6,6 +6,7 @@ #include <limits> #include <string> +#include <vector> #include "base/bind.h" #include "base/callback.h" @@ -154,7 +155,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( filter_collection_->AddAudioRenderer( new media::AudioRendererImpl(new media::NullAudioSink())); - decryptor_.reset(new media::AesDecryptor()); + decryptor_.reset(new media::AesDecryptor(proxy_.get())); } WebMediaPlayerImpl::~WebMediaPlayerImpl() { @@ -690,7 +691,7 @@ void WebMediaPlayerImpl::sourceEndOfStream( DCHECK_EQ(main_loop_, MessageLoop::current()); media::PipelineStatus pipeline_status = media::PIPELINE_OK; - switch(status) { + switch (status) { case WebMediaPlayer::EndOfStreamStatusNoError: break; case WebMediaPlayer::EndOfStreamStatusNetworkError: @@ -713,36 +714,12 @@ WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system, if (!IsSupportedKeySystem(key_system)) return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; - // Every request call creates a unique ID. - // TODO(ddorwin): Move this to the CDM implementations since the CDMs may - // create their own IDs and since CDMs supporting multiple renderer processes - // need globally unique IDs. - // Everything from here until the return should probably be handled by - // the decryptor - see http://crbug.com/123260. - static uint32_t next_available_session_id = 1; - uint32_t session_id = next_available_session_id++; - - WebString session_id_string(base::UintToString16(session_id)); - DVLOG(1) << "generateKeyRequest: " << key_system.utf8().data() << ": " << std::string(reinterpret_cast<const char*>(init_data), - static_cast<size_t>(init_data_length)) - << " [" << session_id_string.utf8().data() << "]"; - - // TODO(ddorwin): Generate a key request in the decryptor and fire - // keyMessage when it completes. - // For now, just fire the event with the init_data as the request. - const unsigned char* message = init_data; - unsigned message_length = init_data_length; - - MessageLoop::current()->PostTask(FROM_HERE, base::Bind( - &WebKit::WebMediaPlayerClient::keyMessage, - base::Unretained(GetClient()), - key_system, - session_id_string, - message, - message_length)); + static_cast<size_t>(init_data_length)); + decryptor_->GenerateKeyRequest(key_system.utf8(), + init_data, init_data_length); return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; } @@ -759,7 +736,6 @@ WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( if (!IsSupportedKeySystem(key_system)) return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; - DVLOG(1) << "addKey: " << key_system.utf8().data() << ": " << std::string(reinterpret_cast<const char*>(key), static_cast<size_t>(key_length)) << ", " @@ -767,38 +743,8 @@ WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::addKey( static_cast<size_t>(init_data_length)) << " [" << session_id.utf8().data() << "]"; - // TODO(ddorwin): Everything from here until the return should probably be - // handled by the decryptor - see http://crbug.com/123260. - // Temporarily, fire an error for invalid key length so we can test the error - // event and fire the keyAdded event in all other cases. - const unsigned kSupportedKeyLength = 16; // 128-bit key. - if (key_length != kSupportedKeyLength) { - DLOG(ERROR) << "addKey: invalid key length: " << key_length; - MessageLoop::current()->PostTask(FROM_HERE, base::Bind( - &WebKit::WebMediaPlayerClient::keyError, - base::Unretained(GetClient()), - key_system, - session_id, - WebKit::WebMediaPlayerClient::MediaKeyErrorCodeUnknown, - 0)); - } else { - // TODO(ddorwin): Fix the decryptor to accept no |init_data|. See - // http://crbug.com/123265. Until then, ensure a non-empty value is passed. - static const unsigned char kDummyInitData[1] = {0}; - if (!init_data) { - init_data = kDummyInitData; - init_data_length = arraysize(kDummyInitData); - } - - decryptor_->AddKey(init_data, init_data_length, key, key_length); - - MessageLoop::current()->PostTask(FROM_HERE, base::Bind( - &WebKit::WebMediaPlayerClient::keyAdded, - base::Unretained(GetClient()), - key_system, - session_id)); - } - + decryptor_->AddKey(key_system.utf8(), key, key_length, + init_data, init_data_length, session_id.utf8()); return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; } @@ -808,8 +754,7 @@ WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest( if (!IsSupportedKeySystem(key_system)) return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; - // TODO(ddorwin): Cancel the key request in the decryptor. - + decryptor_->CancelKeyRequest(key_system.utf8(), session_id.utf8()); return WebKit::WebMediaPlayer::MediaKeyExceptionNoError; } @@ -926,11 +871,50 @@ void WebMediaPlayerImpl::OnDemuxerOpened() { GetClient()->sourceOpened(); } -void WebMediaPlayerImpl::OnKeyNeeded(scoped_array<uint8> init_data, - int init_data_size) { +void WebMediaPlayerImpl::OnKeyAdded(const std::string& key_system, + const std::string& session_id) { + DCHECK_EQ(main_loop_, MessageLoop::current()); + + GetClient()->keyAdded(WebString::fromUTF8(key_system), + WebString::fromUTF8(session_id)); +} + +void WebMediaPlayerImpl::OnNeedKey(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> init_data, + int init_data_size) { + DCHECK_EQ(main_loop_, MessageLoop::current()); + + GetClient()->keyNeeded(WebString::fromUTF8(key_system), + WebString::fromUTF8(session_id), + init_data.get(), + init_data_size); +} + +void WebMediaPlayerImpl::OnKeyError(const std::string& key_system, + const std::string& session_id, + media::AesDecryptor::KeyError error_code, + int system_code) { + DCHECK_EQ(main_loop_, MessageLoop::current()); + + GetClient()->keyError( + WebString::fromUTF8(key_system), + WebString::fromUTF8(session_id), + static_cast<WebKit::WebMediaPlayerClient::MediaKeyErrorCode>(error_code), + system_code); +} + +void WebMediaPlayerImpl::OnKeyMessage(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> message, + int message_length, + const std::string& /* default_url */) { DCHECK_EQ(main_loop_, MessageLoop::current()); - GetClient()->keyNeeded("", "", init_data.get(), init_data_size); + GetClient()->keyMessage(WebString::fromUTF8(key_system), + WebString::fromUTF8(session_id), + message.get(), + message_length); } void WebMediaPlayerImpl::SetOpaque(bool opaque) { diff --git a/webkit/media/webmediaplayer_impl.h b/webkit/media/webmediaplayer_impl.h index 6ef94b2..30d15f0 100644 --- a/webkit/media/webmediaplayer_impl.h +++ b/webkit/media/webmediaplayer_impl.h @@ -48,6 +48,8 @@ #ifndef WEBKIT_MEDIA_WEBMEDIAPLAYER_IMPL_H_ #define WEBKIT_MEDIA_WEBMEDIAPLAYER_IMPL_H_ +#include <string> + #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" @@ -57,6 +59,7 @@ #include "media/base/filters.h" #include "media/base/message_loop_factory.h" #include "media/base/pipeline.h" +#include "media/crypto/aes_decryptor.h" #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebAudioSourceProvider.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayer.h" @@ -213,7 +216,6 @@ class WebMediaPlayerImpl const WebKit::WebString& key_system, const WebKit::WebString& session_id); - // As we are closing the tab or even the browser, |main_loop_| is destroyed // even before this object gets destructed, so we need to know when // |main_loop_| is being destroyed and we can stop posting repaint task @@ -227,7 +229,20 @@ class WebMediaPlayerImpl void OnPipelineEnded(media::PipelineStatus status); void OnPipelineError(media::PipelineStatus error); void OnDemuxerOpened(); - void OnKeyNeeded(scoped_array<uint8> init_data, int init_data_size); + void OnKeyAdded(const std::string& key_system, const std::string& session_id); + void OnKeyError(const std::string& key_system, + const std::string& session_id, + media::AesDecryptor::KeyError error_code, + int system_code); + void OnKeyMessage(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> message, + int message_length, + const std::string& default_url); + void OnNeedKey(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> init_data, + int init_data_size); void SetOpaque(bool); private: diff --git a/webkit/media/webmediaplayer_proxy.cc b/webkit/media/webmediaplayer_proxy.cc index fdbd544..461f67e 100644 --- a/webkit/media/webmediaplayer_proxy.cc +++ b/webkit/media/webmediaplayer_proxy.cc @@ -177,10 +177,10 @@ void WebMediaPlayerProxy::DemuxerClosed() { &WebMediaPlayerProxy::DemuxerClosedTask, this)); } -void WebMediaPlayerProxy::KeyNeeded(scoped_array<uint8> init_data, - int init_data_size) { +void WebMediaPlayerProxy::DemuxerNeedKey(scoped_array<uint8> init_data, + int init_data_size) { render_loop_->PostTask(FROM_HERE, base::Bind( - &WebMediaPlayerProxy::KeyNeededTask, this, + &WebMediaPlayerProxy::NeedKeyTask, this, "", "", base::Passed(&init_data), init_data_size)); } @@ -237,11 +237,76 @@ void WebMediaPlayerProxy::DemuxerClosedTask() { chunk_demuxer_ = NULL; } -void WebMediaPlayerProxy::KeyNeededTask(scoped_array<uint8> init_data, - int init_data_size) { +void WebMediaPlayerProxy::KeyAdded(const std::string& key_system, + const std::string& session_id) { + render_loop_->PostTask(FROM_HERE, base::Bind( + &WebMediaPlayerProxy::KeyAddedTask, this, key_system, session_id)); +} + +void WebMediaPlayerProxy::KeyError(const std::string& key_system, + const std::string& session_id, + media::AesDecryptor::KeyError error_code, + int system_code) { + render_loop_->PostTask(FROM_HERE, base::Bind( + &WebMediaPlayerProxy::KeyErrorTask, this, key_system, session_id, + error_code, system_code)); +} + +void WebMediaPlayerProxy::KeyMessage(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> message, + int message_length, + const std::string& default_url) { + render_loop_->PostTask(FROM_HERE, base::Bind( + &WebMediaPlayerProxy::KeyMessageTask, this, key_system, session_id, + base::Passed(&message), message_length, default_url)); +} + +void WebMediaPlayerProxy::NeedKey(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> init_data, + int init_data_size) { + render_loop_->PostTask(FROM_HERE, base::Bind( + &WebMediaPlayerProxy::NeedKeyTask, this, key_system, session_id, + base::Passed(&init_data), init_data_size)); +} + +void WebMediaPlayerProxy::KeyAddedTask(const std::string& key_system, + const std::string& session_id) { + DCHECK(render_loop_->BelongsToCurrentThread()); + if (webmediaplayer_) + webmediaplayer_->OnKeyAdded(key_system, session_id); +} + +void WebMediaPlayerProxy::KeyErrorTask(const std::string& key_system, + const std::string& session_id, + media::AesDecryptor::KeyError error_code, + int system_code) { + DCHECK(render_loop_->BelongsToCurrentThread()); + if (webmediaplayer_) + webmediaplayer_->OnKeyError(key_system, session_id, + error_code, system_code); +} + +void WebMediaPlayerProxy::KeyMessageTask(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> message, + int message_length, + const std::string& default_url) { + DCHECK(render_loop_->BelongsToCurrentThread()); + if (webmediaplayer_) + webmediaplayer_->OnKeyMessage(key_system, session_id, + message.Pass(), message_length, default_url); +} + +void WebMediaPlayerProxy::NeedKeyTask(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> init_data, + int init_data_size) { DCHECK(render_loop_->BelongsToCurrentThread()); if (webmediaplayer_) - webmediaplayer_->OnKeyNeeded(init_data.Pass(), init_data_size); + webmediaplayer_->OnNeedKey(key_system, session_id, + init_data.Pass(), init_data_size); } } // namespace webkit_media diff --git a/webkit/media/webmediaplayer_proxy.h b/webkit/media/webmediaplayer_proxy.h index f958f5d..2416388 100644 --- a/webkit/media/webmediaplayer_proxy.h +++ b/webkit/media/webmediaplayer_proxy.h @@ -12,6 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" #include "media/base/pipeline.h" +#include "media/crypto/decryptor_client.h" #include "media/filters/chunk_demuxer.h" #include "media/filters/chunk_demuxer_client.h" #include "media/filters/ffmpeg_video_decoder.h" @@ -41,7 +42,8 @@ class WebMediaPlayerImpl; // the render thread that WebMediaPlayerImpl is running on. class WebMediaPlayerProxy : public base::RefCountedThreadSafe<WebMediaPlayerProxy>, - public media::ChunkDemuxerClient { + public media::ChunkDemuxerClient, + public media::DecryptorClient { public: WebMediaPlayerProxy(const scoped_refptr<base::MessageLoopProxy>& render_loop, WebMediaPlayerImpl* webmediaplayer); @@ -89,8 +91,8 @@ class WebMediaPlayerProxy // ChunkDemuxerClient implementation. virtual void DemuxerOpened(media::ChunkDemuxer* demuxer) OVERRIDE; virtual void DemuxerClosed() OVERRIDE; - virtual void KeyNeeded(scoped_array<uint8> init_data, - int init_data_size) OVERRIDE; + virtual void DemuxerNeedKey(scoped_array<uint8> init_data, + int init_data_size) OVERRIDE; // Methods for Demuxer communication. void DemuxerStartWaitingForSeek(); @@ -105,9 +107,22 @@ class WebMediaPlayerProxy void DemuxerEndOfStream(media::PipelineStatus status); void DemuxerShutdown(); - void DemuxerOpenedTask(const scoped_refptr<media::ChunkDemuxer>& demuxer); - void DemuxerClosedTask(); - void KeyNeededTask(scoped_array<uint8> init_data, int init_data_size); + // DecryptorClient implementation. + virtual void KeyAdded(const std::string& key_system, + const std::string& session_id) OVERRIDE; + virtual void KeyError(const std::string& key_system, + const std::string& session_id, + media::AesDecryptor::KeyError error_code, + int system_code) OVERRIDE; + virtual void KeyMessage(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> message, + int message_length, + const std::string& default_url) OVERRIDE; + virtual void NeedKey(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> init_data, + int init_data_size) OVERRIDE; private: friend class base::RefCountedThreadSafe<WebMediaPlayerProxy>; @@ -132,6 +147,32 @@ class WebMediaPlayerProxy // Inform |webmediaplayer_| whether the video content is opaque. void SetOpaqueTask(bool opaque); + void DemuxerOpenedTask(const scoped_refptr<media::ChunkDemuxer>& demuxer); + void DemuxerClosedTask(); + + // Notify |webmediaplayer_| that a key has been added. + void KeyAddedTask(const std::string& key_system, + const std::string& session_id); + + // Notify |webmediaplayer_| that a key error occurred. + void KeyErrorTask(const std::string& key_system, + const std::string& session_id, + media::AesDecryptor::KeyError error_code, + int system_code); + + // Notify |webmediaplayer_| that a key message has been generated. + void KeyMessageTask(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> message, + int message_length, + const std::string& default_url); + + // Notify |webmediaplayer_| that a key is needed for decryption. + void NeedKeyTask(const std::string& key_system, + const std::string& session_id, + scoped_array<uint8> init_data, + int init_data_size); + // The render message loop where WebKit lives. scoped_refptr<base::MessageLoopProxy> render_loop_; WebMediaPlayerImpl* webmediaplayer_; |