summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-19 09:45:56 +0000
committerddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-19 09:45:56 +0000
commitf7a6b9990c8770ebce219a863b156b7c8e150f60 (patch)
treefb400719a0292f67ba4c4e4353a4ec6aa65d750d
parentbec20dd23bdd936f7dea25da7367432a26d4f7a9 (diff)
downloadchromium_src-f7a6b9990c8770ebce219a863b156b7c8e150f60.zip
chromium_src-f7a6b9990c8770ebce219a863b156b7c8e150f60.tar.gz
chromium_src-f7a6b9990c8770ebce219a863b156b7c8e150f60.tar.bz2
Initial implementation of Encrypted Media Extensions in Chrome.
The new encrypted-media layout tests pass, but the key is not used by the media stack yet. BUG=119668 TEST=LayoutTests/media/encrypted-media/ R=scherkus@chromium.org Review URL: http://codereview.chromium.org/10020053 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132973 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/worker/worker_webkitplatformsupport_impl.cc7
-rw-r--r--content/worker/worker_webkitplatformsupport_impl.h5
-rw-r--r--webkit/glue/simple_webmimeregistry_impl.cc41
-rw-r--r--webkit/glue/simple_webmimeregistry_impl.h5
-rw-r--r--webkit/media/key_systems.cc78
-rw-r--r--webkit/media/key_systems.h30
-rw-r--r--webkit/media/webkit_media.gypi2
-rw-r--r--webkit/media/webmediaplayer_impl.cc100
-rw-r--r--webkit/media/webmediaplayer_impl.h17
-rw-r--r--webkit/tools/layout_tests/test_expectations.txt1
-rw-r--r--webkit/tools/test_shell/test_shell_webmimeregistry_impl.cc6
-rw-r--r--webkit/tools/test_shell/test_shell_webmimeregistry_impl.h1
12 files changed, 283 insertions, 10 deletions
diff --git a/content/worker/worker_webkitplatformsupport_impl.cc b/content/worker/worker_webkitplatformsupport_impl.cc
index daa80504..45a2552 100644
--- a/content/worker/worker_webkitplatformsupport_impl.cc
+++ b/content/worker/worker_webkitplatformsupport_impl.cc
@@ -242,6 +242,13 @@ WorkerWebKitPlatformSupportImpl::supportsMediaMIMEType(
}
WebMimeRegistry::SupportsType
+WorkerWebKitPlatformSupportImpl::supportsMediaMIMEType(
+ const WebString&, const WebString&, const WebString&) {
+ NOTREACHED();
+ return WebMimeRegistry::IsSupported;
+}
+
+WebMimeRegistry::SupportsType
WorkerWebKitPlatformSupportImpl::supportsNonImageMIMEType(
const WebString&) {
NOTREACHED();
diff --git a/content/worker/worker_webkitplatformsupport_impl.h b/content/worker/worker_webkitplatformsupport_impl.h
index 69aea47..339146c 100644
--- a/content/worker/worker_webkitplatformsupport_impl.h
+++ b/content/worker/worker_webkitplatformsupport_impl.h
@@ -72,8 +72,13 @@ class WorkerWebKitPlatformSupportImpl
const WebKit::WebString&);
virtual WebKit::WebMimeRegistry::SupportsType supportsJavaScriptMIMEType(
const WebKit::WebString&);
+ // TODO(ddorwin): Remove after http://webk.it/82983 lands.
virtual WebKit::WebMimeRegistry::SupportsType supportsMediaMIMEType(
const WebKit::WebString&, const WebKit::WebString&);
+ virtual WebKit::WebMimeRegistry::SupportsType supportsMediaMIMEType(
+ const WebKit::WebString&,
+ const WebKit::WebString&,
+ const WebKit::WebString&);
virtual WebKit::WebMimeRegistry::SupportsType supportsNonImageMIMEType(
const WebKit::WebString&);
virtual WebKit::WebString mimeTypeForExtension(const WebKit::WebString&);
diff --git a/webkit/glue/simple_webmimeregistry_impl.cc b/webkit/glue/simple_webmimeregistry_impl.cc
index 1bc28fa..9a8d212 100644
--- a/webkit/glue/simple_webmimeregistry_impl.cc
+++ b/webkit/glue/simple_webmimeregistry_impl.cc
@@ -10,6 +10,7 @@
#include "net/base/mime_util.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "webkit/glue/webkit_glue.h"
+#include "webkit/media/key_systems.h"
using WebKit::WebString;
using WebKit::WebMimeRegistry;
@@ -45,25 +46,49 @@ WebMimeRegistry::SupportsType
WebMimeRegistry::IsSupported : WebMimeRegistry::IsNotSupported;
}
+// When debugging layout tests failures in the test shell,
+// see TestShellWebMimeRegistryImpl.
+WebMimeRegistry::SupportsType SimpleWebMimeRegistryImpl::supportsMediaMIMEType(
+ const WebString& mime_type, const WebString& codecs) {
+ return supportsMediaMIMEType(mime_type, codecs, WebString());
+}
+
WebMimeRegistry::SupportsType SimpleWebMimeRegistryImpl::supportsMediaMIMEType(
const WebString& mime_type,
- const WebString& codecs) {
+ const WebString& codecs,
+ const WebString& key_system) {
+ const std::string mime_type_ascii = ToASCIIOrEmpty(mime_type);
// Not supporting the container is a flat-out no.
- if (!net::IsSupportedMediaMimeType(ToASCIIOrEmpty(mime_type)))
+ if (!net::IsSupportedMediaMimeType(mime_type_ascii))
return IsNotSupported;
+ if (!key_system.isEmpty()) {
+ // Check whether the key system is supported with the mime_type and codecs.
+
+ // Not supporting the key system is a flat-out no.
+ if (!webkit_media::IsSupportedKeySystem(key_system))
+ return IsNotSupported;
+
+ std::vector<std::string> strict_codecs;
+ net::ParseCodecString(ToASCIIOrEmpty(codecs), &strict_codecs, false);
+
+ if (!webkit_media::IsSupportedKeySystemWithMediaMimeType(
+ mime_type_ascii, strict_codecs, ToASCIIOrEmpty(key_system)))
+ return IsNotSupported;
+
+ // Continue processing the mime_type and codecs.
+ }
+
// Check list of strict codecs to see if it is supported.
- if (net::IsStrictMediaMimeType(ToASCIIOrEmpty(mime_type))) {
+ if (net::IsStrictMediaMimeType(mime_type_ascii)) {
// We support the container, but no codecs were specified.
if (codecs.isNull())
return MayBeSupported;
// Check if the codecs are a perfect match.
std::vector<std::string> strict_codecs;
- net::ParseCodecString(ToASCIIOrEmpty(codecs).c_str(), &strict_codecs,
- false);
- if (!net::IsSupportedStrictMediaMimeType(ToASCIIOrEmpty(mime_type),
- strict_codecs))
+ net::ParseCodecString(ToASCIIOrEmpty(codecs), &strict_codecs, false);
+ if (!net::IsSupportedStrictMediaMimeType(mime_type_ascii, strict_codecs))
return IsNotSupported;
// Good to go!
@@ -72,7 +97,7 @@ WebMimeRegistry::SupportsType SimpleWebMimeRegistryImpl::supportsMediaMIMEType(
// If we don't recognize the codec, it's possible we support it.
std::vector<std::string> parsed_codecs;
- net::ParseCodecString(ToASCIIOrEmpty(codecs).c_str(), &parsed_codecs, true);
+ net::ParseCodecString(ToASCIIOrEmpty(codecs), &parsed_codecs, true);
if (!net::AreSupportedMediaCodecs(parsed_codecs))
return MayBeSupported;
diff --git a/webkit/glue/simple_webmimeregistry_impl.h b/webkit/glue/simple_webmimeregistry_impl.h
index c106dff..a3a0608 100644
--- a/webkit/glue/simple_webmimeregistry_impl.h
+++ b/webkit/glue/simple_webmimeregistry_impl.h
@@ -24,8 +24,13 @@ class WEBKIT_GLUE_EXPORT SimpleWebMimeRegistryImpl :
const WebKit::WebString&);
virtual WebKit::WebMimeRegistry::SupportsType supportsJavaScriptMIMEType(
const WebKit::WebString&);
+ // TODO(ddorwin): Remove after http://webk.it/82983 lands.
virtual WebKit::WebMimeRegistry::SupportsType supportsMediaMIMEType(
const WebKit::WebString&, const WebKit::WebString&);
+ virtual WebKit::WebMimeRegistry::SupportsType supportsMediaMIMEType(
+ const WebKit::WebString&,
+ const WebKit::WebString&,
+ const WebKit::WebString&);
virtual WebKit::WebMimeRegistry::SupportsType supportsNonImageMIMEType(
const WebKit::WebString&);
virtual WebKit::WebString mimeTypeForExtension(const WebKit::WebString&);
diff --git a/webkit/media/key_systems.cc b/webkit/media/key_systems.cc
new file mode 100644
index 0000000..7efbb9e
--- /dev/null
+++ b/webkit/media/key_systems.cc
@@ -0,0 +1,78 @@
+// Copyright (c) 2012 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 "webkit/media/key_systems.h"
+
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
+
+namespace webkit_media {
+
+namespace {
+
+const char kClearKeyKeySystem[] = "webkit-org.w3.clearkey";
+
+struct MediaFormatAndKeySystem {
+ const char* mime_type;
+ const char* codec;
+ const char* key_system;
+};
+
+static const MediaFormatAndKeySystem
+supported_format_key_system_combinations[] = {
+ // TODO(ddorwin): Reconsider based on how usage of this class evolves.
+ // For now, this class is stateless, so we do not have the opportunity to
+ // build a list using ParseCodecString() like
+ // net::MimeUtil::InitializeMimeTypeMaps(). Therfore, the following line must
+ // be separate entries.
+ // { "video/webm", "vorbis,vp8,vp8.0", kClearKeyKeySystem },
+ { "video/webm", "vorbis", kClearKeyKeySystem },
+ { "video/webm", "vp8", kClearKeyKeySystem },
+ { "video/webm", "vp8.0", kClearKeyKeySystem },
+ { "audio/webm", "vorbis", kClearKeyKeySystem },
+ { "video/webm", "", kClearKeyKeySystem },
+ { "audio/webm", "", kClearKeyKeySystem }
+};
+
+bool IsSupportedKeySystemWithContainerAndCodec(const std::string& mime_type,
+ const std::string& codec,
+ const std::string& key_system) {
+ for (size_t i = 0;
+ i < arraysize(supported_format_key_system_combinations);
+ ++i) {
+ const MediaFormatAndKeySystem& combination =
+ supported_format_key_system_combinations[i];
+ if (combination.mime_type == mime_type &&
+ combination.codec == codec &&
+ combination.key_system == key_system)
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+bool IsSupportedKeySystem(const WebKit::WebString& key_system) {
+ if (key_system == kClearKeyKeySystem)
+ return true;
+ return false;
+}
+
+bool IsSupportedKeySystemWithMediaMimeType(
+ const std::string& mime_type,
+ const std::vector<std::string>& codecs,
+ const std::string& key_system) {
+ if (codecs.empty())
+ return IsSupportedKeySystemWithContainerAndCodec(mime_type, "", key_system);
+
+ for (size_t i = 0; i < codecs.size(); ++i) {
+ if (!IsSupportedKeySystemWithContainerAndCodec(
+ mime_type, codecs[i], key_system))
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace webkit_media
diff --git a/webkit/media/key_systems.h b/webkit/media/key_systems.h
new file mode 100644
index 0000000..dedd279
--- /dev/null
+++ b/webkit/media/key_systems.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2012 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 WEBKIT_MEDIA_KEY_SYSTEMS_H_
+#define WEBKIT_MEDIA_KEY_SYSTEMS_H_
+
+#include <string>
+#include <vector>
+
+namespace WebKit {
+class WebString;
+}
+
+namespace webkit_media {
+
+// Returns whether |key_sytem| is supported at all.
+// Call IsSupportedKeySystemWithMediaMimeType() to determine whether a
+// |key_system| supports a specific type of media.
+bool IsSupportedKeySystem(const WebKit::WebString& key_system);
+
+// Returns whether |key_sytem| supports the specified media type and codec(s).
+bool IsSupportedKeySystemWithMediaMimeType(
+ const std::string& mime_type,
+ const std::vector<std::string>& codecs,
+ const std::string& key_system);
+
+} // namespace webkit_media
+
+#endif // WEBKIT_MEDIA_KEY_SYSTEMS_H_
diff --git a/webkit/media/webkit_media.gypi b/webkit/media/webkit_media.gypi
index fb62d19..879a423 100644
--- a/webkit/media/webkit_media.gypi
+++ b/webkit/media/webkit_media.gypi
@@ -25,6 +25,8 @@
'buffered_resource_loader.h',
'filter_helpers.cc',
'filter_helpers.h',
+ 'key_systems.cc',
+ 'key_systems.h',
'media_stream_client.h',
'preload.h',
'skcanvas_video_renderer.cc',
diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc
index 2835799..ad74c22 100644
--- a/webkit/media/webmediaplayer_impl.cc
+++ b/webkit/media/webmediaplayer_impl.cc
@@ -12,6 +12,7 @@
#include "base/command_line.h"
#include "base/message_loop_proxy.h"
#include "base/metrics/histogram.h"
+#include "base/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "media/audio/null_audio_sink.h"
#include "media/base/filter_collection.h"
@@ -26,10 +27,12 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
#include "v8/include/v8.h"
#include "webkit/media/buffered_data_source.h"
#include "webkit/media/filter_helpers.h"
+#include "webkit/media/key_systems.h"
#include "webkit/media/webmediaplayer_delegate.h"
#include "webkit/media/webmediaplayer_proxy.h"
#include "webkit/media/webvideoframe_impl.h"
@@ -38,6 +41,7 @@ using WebKit::WebCanvas;
using WebKit::WebMediaPlayer;
using WebKit::WebRect;
using WebKit::WebSize;
+using WebKit::WebString;
using media::NetworkEvent;
using media::PipelineStatus;
@@ -668,6 +672,102 @@ void WebMediaPlayerImpl::sourceEndOfStream(
proxy_->DemuxerEndOfStream(pipeline_status);
}
+WebKit::WebMediaPlayer::MediaKeyException
+WebMediaPlayerImpl::generateKeyRequest(const WebString& key_system,
+ const unsigned char* init_data,
+ unsigned init_data_length) {
+ 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 decrypter - 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 decrypter 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));
+
+ return WebKit::WebMediaPlayer::MediaKeyExceptionNoError;
+}
+
+WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::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) {
+ 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)) << ", "
+ << std::string(reinterpret_cast<const char*>(init_data),
+ static_cast<size_t>(init_data_length))
+ << " [" << session_id.utf8().data() << "]";
+
+ // TODO(ddorwin): Add the key to the decrypter and fire keyAdded when it
+ // completes. Check the key length there.
+ // Everything from here until the return should probably be handled by
+ // the decrypter - 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 {
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
+ &WebKit::WebMediaPlayerClient::keyAdded,
+ base::Unretained(GetClient()),
+ key_system,
+ session_id));
+ }
+
+ return WebKit::WebMediaPlayer::MediaKeyExceptionNoError;
+}
+
+WebKit::WebMediaPlayer::MediaKeyException WebMediaPlayerImpl::cancelKeyRequest(
+ const WebString& key_system,
+ const WebString& session_id) {
+ if (!IsSupportedKeySystem(key_system))
+ return WebKit::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
+
+ // TODO(ddorwin): Cancel the key request in the decrypter.
+
+ return WebKit::WebMediaPlayer::MediaKeyExceptionNoError;
+}
+
void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() {
Destroy();
main_loop_ = NULL;
diff --git a/webkit/media/webmediaplayer_impl.h b/webkit/media/webmediaplayer_impl.h
index fc803a3..ae1e889 100644
--- a/webkit/media/webmediaplayer_impl.h
+++ b/webkit/media/webmediaplayer_impl.h
@@ -184,6 +184,23 @@ class WebMediaPlayerImpl
virtual bool sourceAppend(const unsigned char* data, unsigned length);
virtual void sourceEndOfStream(EndOfStreamStatus status);
+ virtual MediaKeyException generateKeyRequest(
+ const WebKit::WebString& key_system,
+ const unsigned char* init_data,
+ unsigned init_data_length);
+
+ virtual MediaKeyException addKey(const WebKit::WebString& key_system,
+ const unsigned char* key,
+ unsigned key_length,
+ const unsigned char* init_data,
+ unsigned init_data_length,
+ const WebKit::WebString& session_id);
+
+ virtual MediaKeyException cancelKeyRequest(
+ 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
diff --git a/webkit/tools/layout_tests/test_expectations.txt b/webkit/tools/layout_tests/test_expectations.txt
index 9d262f1..0ed3dbcf 100644
--- a/webkit/tools/layout_tests/test_expectations.txt
+++ b/webkit/tools/layout_tests/test_expectations.txt
@@ -54,3 +54,4 @@ BUGCR123680 : fast/repaint/shadow-multiple-vertical.html = IMAGE
BUGCR123680 : svg/W3C-SVG-1.1/masking-intro-01-f.svg = IMAGE
BUGCR123809 : fast/borders/border-radius-groove-02.html = IMAGE
+BUGWK82983 : media/encrypted-media/ = PASS
diff --git a/webkit/tools/test_shell/test_shell_webmimeregistry_impl.cc b/webkit/tools/test_shell/test_shell_webmimeregistry_impl.cc
index ebc19e2..e08842b 100644
--- a/webkit/tools/test_shell/test_shell_webmimeregistry_impl.cc
+++ b/webkit/tools/test_shell/test_shell_webmimeregistry_impl.cc
@@ -35,7 +35,8 @@ TestShellWebMimeRegistryImpl::~TestShellWebMimeRegistryImpl() {}
WebMimeRegistry::SupportsType
TestShellWebMimeRegistryImpl::supportsMediaMIMEType(
const WebString& mime_type,
- const WebString& codecs) {
+ const WebString& codecs,
+ const WebKit::WebString& key_system) {
if (IsBlacklistedMediaMimeType(ToASCIIOrEmpty(mime_type)))
return IsNotSupported;
@@ -44,7 +45,8 @@ TestShellWebMimeRegistryImpl::supportsMediaMIMEType(
if (HasBlacklistedMediaCodecs(parsed_codecs))
return IsNotSupported;
- return SimpleWebMimeRegistryImpl::supportsMediaMIMEType(mime_type, codecs);
+ return SimpleWebMimeRegistryImpl::supportsMediaMIMEType(
+ mime_type, codecs, key_system);
}
bool TestShellWebMimeRegistryImpl::IsBlacklistedMediaMimeType(
diff --git a/webkit/tools/test_shell/test_shell_webmimeregistry_impl.h b/webkit/tools/test_shell/test_shell_webmimeregistry_impl.h
index 40ac863..6fcff259 100644
--- a/webkit/tools/test_shell/test_shell_webmimeregistry_impl.h
+++ b/webkit/tools/test_shell/test_shell_webmimeregistry_impl.h
@@ -29,6 +29,7 @@ class TestShellWebMimeRegistryImpl
// layout tests.
virtual WebKit::WebMimeRegistry::SupportsType supportsMediaMIMEType(
const WebKit::WebString&,
+ const WebKit::WebString&,
const WebKit::WebString&) OVERRIDE;
private: