summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-16 01:27:36 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-16 01:27:36 +0000
commitcbdc8c2b4b46c7e7886c9e99bc595a0b9936b381 (patch)
treefd03ab4a8636680c4c2dff01880751e25ef0cdca /webkit
parent46b7d64e85a9d8d28372d05b59b295dd6ecb0bc8 (diff)
downloadchromium_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.cc118
-rw-r--r--webkit/media/webmediaplayer_impl.h19
-rw-r--r--webkit/media/webmediaplayer_proxy.cc77
-rw-r--r--webkit/media/webmediaplayer_proxy.h53
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_;