Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Unified Diff: Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp

Issue 157423003: Remove the dependency on encryptedmedia from HTMLMediaElement. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Address review comments. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
diff --git a/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp b/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a9fd9af5dfa9ca74e326e8e76e1c08f9fb52371
--- /dev/null
+++ b/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
@@ -0,0 +1,353 @@
+// Copyright 2014 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 "config.h"
+#include "modules/encryptedmedia/HTMLMediaElementEncryptedMedia.h"
+
+#include "RuntimeEnabledFeatures.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/MediaKeyError.h"
+#include "core/html/MediaKeyEvent.h"
+#include "modules/encryptedmedia/MediaKeyNeededEvent.h"
+#include "modules/encryptedmedia/MediaKeys.h"
+#include "platform/Logging.h"
+
+namespace WebCore {
+
+static void throwExceptionForMediaKeyException(const String& keySystem, const String& sessionId, blink::WebMediaPlayer::MediaKeyException exception, ExceptionState& exceptionState)
+{
+ switch (exception) {
+ case blink::WebMediaPlayer::MediaKeyExceptionNoError:
+ return;
+ case blink::WebMediaPlayer::MediaKeyExceptionInvalidPlayerState:
+ exceptionState.throwDOMException(InvalidStateError, "The player is in an invalid state.");
+ return;
+ case blink::WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported:
+ exceptionState.throwDOMException(NotSupportedError, "The key system provided ('" + keySystem +"') is not supported.");
+ return;
+ case blink::WebMediaPlayer::MediaKeyExceptionInvalidAccess:
+ exceptionState.throwDOMException(InvalidAccessError, "The session ID provided ('" + sessionId + "') is invalid.");
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+ return;
+}
+
+HTMLMediaElementEncryptedMedia::HTMLMediaElementEncryptedMedia()
+ : m_emeMode(EmeModeNotSelected)
+{
+}
+
+HTMLMediaElementEncryptedMedia::~HTMLMediaElementEncryptedMedia()
+{
+}
+
+const char* HTMLMediaElementEncryptedMedia::supplementName()
+{
+ return "HTMLMediaElementEncryptedMedia";
+}
+
+HTMLMediaElementEncryptedMedia& HTMLMediaElementEncryptedMedia::from(HTMLMediaElement& element)
+{
+ HTMLMediaElementEncryptedMedia* supplement = static_cast<HTMLMediaElementEncryptedMedia*>(Supplement<HTMLMediaElement>::from(element, supplementName()));
ddorwin 2014/02/27 00:37:59 Wouldn't it be better to do the case to this Suppl
c.shu 2014/02/27 14:49:46 Done.
+ if (!supplement) {
+ supplement = new HTMLMediaElementEncryptedMedia();
+ provideTo(element, supplementName(), adoptPtr(supplement));
+ }
+ return *supplement;
+}
+
+bool HTMLMediaElementEncryptedMedia::setEmeMode(EmeMode emeMode, ExceptionState& exceptionState)
+{
+ if (m_emeMode != EmeModeNotSelected && m_emeMode != emeMode) {
+ exceptionState.throwDOMException(InvalidStateError, "Mixed use of EME prefixed and unprefixed API not allowed.");
+ return false;
+ }
+ m_emeMode = emeMode;
+ return true;
+}
+
+blink::WebContentDecryptionModule* HTMLMediaElementEncryptedMedia::contentDecryptionModule()
+{
+ return m_mediaKeys ? m_mediaKeys->contentDecryptionModule() : 0;
+}
+
+MediaKeys* HTMLMediaElementEncryptedMedia::mediaKeys(HTMLMediaElement& element)
+{
+ HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia::from(element);
+ return thisElement.m_mediaKeys.get();
+}
+
+void HTMLMediaElementEncryptedMedia::setMediaKeysInternal(HTMLMediaElement& element, MediaKeys* mediaKeys)
+{
+ WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::setMediaKeys");
ddorwin 2014/02/27 00:37:59 Update function name and/or move to 105.
c.shu 2014/02/27 14:49:46 Done.
+ if (m_mediaKeys == mediaKeys)
+ return;
+
+ ASSERT(m_emeMode = EmeModeUnprefixed);
+
+ if (m_mediaKeys)
+ m_mediaKeys->setMediaElement(0);
+ m_mediaKeys = mediaKeys;
+ if (m_mediaKeys)
+ m_mediaKeys->setMediaElement(&element);
+
+ // If a player is connected, tell it that the CDM has changed.
+ if (element.webMediaPlayer())
+ element.webMediaPlayer()->setContentDecryptionModule(contentDecryptionModule());
+}
+
+void HTMLMediaElementEncryptedMedia::setMediaKeys(HTMLMediaElement& element, MediaKeys* mediaKeys, ExceptionState& exceptionState)
+{
+ HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia::from(element);
+
+ if (!thisElement.setEmeMode(EmeModeUnprefixed, exceptionState))
+ return;
+
+ thisElement.setMediaKeysInternal(element, mediaKeys);
+}
+
+// Create a MediaKeyNeededEvent for WD EME.
+static PassRefPtr<Event> createNeedKeyEvent(const String& contentType, const unsigned char* initData, unsigned initDataLength)
+{
+ MediaKeyNeededEventInit initializer;
+ initializer.contentType = contentType;
+ initializer.initData = Uint8Array::create(initData, initDataLength);
+ initializer.bubbles = false;
+ initializer.cancelable = false;
+
+ return MediaKeyNeededEvent::create(EventTypeNames::needkey, initializer);
ddorwin 2014/02/27 00:37:59 Blink experts: Is it possible to make the event na
+}
+
+// Create a 'needkey' MediaKeyEvent for v0.1b EME.
+static PassRefPtr<Event> createWebkitNeedKeyEvent(const String& contentType, const unsigned char* initData, unsigned initDataLength)
+{
+ MediaKeyEventInit webkitInitializer;
+ webkitInitializer.keySystem = String();
+ webkitInitializer.sessionId = String();
+ webkitInitializer.initData = Uint8Array::create(initData, initDataLength);
+ webkitInitializer.bubbles = false;
+ webkitInitializer.cancelable = false;
+
+ return MediaKeyEvent::create(EventTypeNames::webkitneedkey, webkitInitializer);
+}
+
+void HTMLMediaElementEncryptedMedia::webkitGenerateKeyRequest(HTMLMediaElement& element, const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState& exceptionState)
ddorwin 2014/02/27 00:37:59 These lines seem long even for Blink.
+{
+ HTMLMediaElementEncryptedMedia::from(element).generateKeyRequest(element.player(), element.webMediaPlayer(), keySystem, initData, exceptionState);
ddorwin 2014/02/27 00:37:59 Would it be better to just pass the element and le
c.shu 2014/03/02 15:35:05 Done.
+}
+
+void HTMLMediaElementEncryptedMedia::generateKeyRequest(bool hasPlayer, blink::WebMediaPlayer* webMediaPlayer, const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState& exceptionState)
ddorwin 2014/02/27 00:37:59 I don't think we need |hasPlayer| - see below.
c.shu 2014/03/02 15:35:05 Done.
+{
+ WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitGenerateKeyRequest");
+
+ if (!setEmeMode(EmeModePrefixed, exceptionState))
+ return;
+
+ if (keySystem.isEmpty()) {
+ exceptionState.throwDOMException(SyntaxError, "The key system provided is empty.");
+ return;
+ }
+
+ if (!hasPlayer) {
ddorwin 2014/02/27 00:37:59 Do we really need this parameter? If we instead ch
c.shu 2014/02/27 14:49:46 There are cases when the player is not null but we
ddorwin 2014/03/01 01:08:47 In what way? Is the exception message different or
c.shu 2014/03/02 15:35:05 Done.
+ exceptionState.throwDOMException(InvalidStateError, "No media has been loaded.");
+ return;
+ }
+
+ const unsigned char* initDataPointer = 0;
+ unsigned initDataLength = 0;
+ if (initData) {
+ initDataPointer = initData->data();
+ initDataLength = initData->length();
+ }
+
+ blink::WebMediaPlayer::MediaKeyException result = webMediaPlayer ? webMediaPlayer->generateKeyRequest(keySystem, initDataPointer, initDataLength) : blink::WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
ddorwin 2014/02/27 00:37:59 This is too confusing and long. If we don't have a
acolwell GONE FROM CHROMIUM 2014/02/27 01:11:11 Ultimately, I think this code should just care abo
c.shu 2014/02/27 14:49:46 Right. If we can update the expected result, the c
ddorwin 2014/03/01 01:08:47 Yes, please do. See above.
c.shu 2014/03/02 15:35:05 Done.
+ throwExceptionForMediaKeyException(keySystem, String(), result, exceptionState);
+}
+
+void HTMLMediaElementEncryptedMedia::webkitGenerateKeyRequest(HTMLMediaElement& mediaElement, const String& keySystem, ExceptionState& exceptionState)
+{
+ webkitGenerateKeyRequest(mediaElement, keySystem, Uint8Array::create(0), exceptionState);
+}
+
+void HTMLMediaElementEncryptedMedia::webkitAddKey(HTMLMediaElement& element, const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState& exceptionState)
+{
+ HTMLMediaElementEncryptedMedia::from(element).addKey(element.player(), element.webMediaPlayer(), keySystem, key, initData, sessionId, exceptionState);
+}
+
+void HTMLMediaElementEncryptedMedia::addKey(bool hasPlayer, blink::WebMediaPlayer* webMediaPlayer, const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState& exceptionState)
+{
+ WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitAddKey");
+
+ if (!setEmeMode(EmeModePrefixed, exceptionState))
+ return;
+
+ if (keySystem.isEmpty()) {
+ exceptionState.throwDOMException(SyntaxError, "The key system provided is empty.");
+ return;
+ }
+
+ if (!key) {
+ exceptionState.throwDOMException(SyntaxError, "The key provided is invalid.");
+ return;
+ }
+
+ if (!key->length()) {
+ exceptionState.throwDOMException(TypeMismatchError, "The key provided is invalid.");
+ return;
+ }
+
+ if (!hasPlayer) {
ddorwin 2014/02/27 00:37:59 ditto here and below.
+ exceptionState.throwDOMException(InvalidStateError, "No media has been loaded.");
+ return;
+ }
+
+ const unsigned char* initDataPointer = 0;
+ unsigned initDataLength = 0;
+ if (initData) {
+ initDataPointer = initData->data();
+ initDataLength = initData->length();
+ }
+
+ blink::WebMediaPlayer::MediaKeyException result = webMediaPlayer ? webMediaPlayer->addKey(keySystem, key->data(), key->length(), initDataPointer, initDataLength, sessionId) : blink::WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
+ throwExceptionForMediaKeyException(keySystem, sessionId, result, exceptionState);
+}
+
+void HTMLMediaElementEncryptedMedia::webkitAddKey(HTMLMediaElement& mediaElement, const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionState& exceptionState)
+{
+ webkitAddKey(mediaElement, keySystem, key, Uint8Array::create(0), String(), exceptionState);
+}
+
+void HTMLMediaElementEncryptedMedia::webkitCancelKeyRequest(HTMLMediaElement& element, const String& keySystem, const String& sessionId, ExceptionState& exceptionState)
+{
+ HTMLMediaElementEncryptedMedia::from(element).cancelKeyRequest(element.player(), element.webMediaPlayer(), keySystem, sessionId, exceptionState);
+}
+
+void HTMLMediaElementEncryptedMedia::cancelKeyRequest(bool hasPlayer, blink::WebMediaPlayer* webMediaPlayer, const String& keySystem, const String& sessionId, ExceptionState& exceptionState)
+{
+ WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::webkitCancelKeyRequest");
+
+ if (!setEmeMode(EmeModePrefixed, exceptionState))
+ return;
+
+ if (keySystem.isEmpty()) {
+ exceptionState.throwDOMException(SyntaxError, "The key system provided is empty.");
+ return;
+ }
+
+ if (!hasPlayer) {
ddorwin 2014/02/27 00:37:59 ditto
+ exceptionState.throwDOMException(InvalidStateError, "No media has been loaded.");
+ return;
+ }
+
+ blink::WebMediaPlayer::MediaKeyException result = webMediaPlayer ? webMediaPlayer->cancelKeyRequest(keySystem, sessionId) : blink::WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
+ throwExceptionForMediaKeyException(keySystem, sessionId, result, exceptionState);
+}
+
+void HTMLMediaElementEncryptedMedia::keyAdded(HTMLMediaElement& element, const String& keySystem, const String& sessionId)
+{
+ WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::mediaPlayerKeyAdded");
+
+ MediaKeyEventInit initializer;
+ initializer.keySystem = keySystem;
+ initializer.sessionId = sessionId;
+ initializer.bubbles = false;
+ initializer.cancelable = false;
+
+ RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeyadded, initializer);
+ event->setTarget(&element);
+ element.scheduleEvent(event.release());
+}
+
+void HTMLMediaElementEncryptedMedia::keyError(HTMLMediaElement& element, const String& keySystem, const String& sessionId, blink::WebMediaPlayerClient::MediaKeyErrorCode errorCode, unsigned short systemCode)
+{
+ WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::mediaPlayerKeyError: sessionID=%s, errorCode=%d, systemCode=%d", sessionId.utf8().data(), errorCode, systemCode);
+
+ MediaKeyError::Code mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
+ switch (errorCode) {
+ case blink::WebMediaPlayerClient::MediaKeyErrorCodeUnknown:
+ mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
+ break;
+ case blink::WebMediaPlayerClient::MediaKeyErrorCodeClient:
+ mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_CLIENT;
+ break;
+ case blink::WebMediaPlayerClient::MediaKeyErrorCodeService:
+ mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_SERVICE;
+ break;
+ case blink::WebMediaPlayerClient::MediaKeyErrorCodeOutput:
+ mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_OUTPUT;
+ break;
+ case blink::WebMediaPlayerClient::MediaKeyErrorCodeHardwareChange:
+ mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_HARDWARECHANGE;
+ break;
+ case blink::WebMediaPlayerClient::MediaKeyErrorCodeDomain:
+ mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_DOMAIN;
+ break;
+ }
+
+ MediaKeyEventInit initializer;
+ initializer.keySystem = keySystem;
+ initializer.sessionId = sessionId;
+ initializer.errorCode = MediaKeyError::create(mediaKeyErrorCode);
+ initializer.systemCode = systemCode;
+ initializer.bubbles = false;
+ initializer.cancelable = false;
+
+ RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeyerror, initializer);
+ event->setTarget(&element);
+ element.scheduleEvent(event.release());
+}
+
+void HTMLMediaElementEncryptedMedia::keyMessage(HTMLMediaElement& element, const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const blink::WebURL& defaultURL)
+{
+ WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::mediaPlayerKeyMessage: sessionID=%s", sessionId.utf8().data());
+
+ MediaKeyEventInit initializer;
+ initializer.keySystem = keySystem;
+ initializer.sessionId = sessionId;
+ initializer.message = Uint8Array::create(message, messageLength);
+ initializer.defaultURL = KURL(defaultURL);
+ initializer.bubbles = false;
+ initializer.cancelable = false;
+
+ RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeymessage, initializer);
+ event->setTarget(&element);
+ element.scheduleEvent(event.release());
+}
+
+void HTMLMediaElementEncryptedMedia::keyNeeded(HTMLMediaElement& element, const String& contentType, const unsigned char* initData, unsigned initDataLength)
+{
+ WTF_LOG(Media, "HTMLMediaElementEncryptedMedia::mediaPlayerKeyNeeded: contentType=%s", contentType.utf8().data());
+
+ if (RuntimeEnabledFeatures::encryptedMediaEnabled()) {
+ // Send event for WD EME.
+ RefPtr<Event> event = createNeedKeyEvent(contentType, initData, initDataLength);
+ event->setTarget(&element);
+ element.scheduleEvent(event.release());
+ }
+
+ if (RuntimeEnabledFeatures::prefixedEncryptedMediaEnabled()) {
+ // Send event for v0.1b EME.
+ RefPtr<Event> event = createWebkitNeedKeyEvent(contentType, initData, initDataLength);
+ event->setTarget(&element);
+ element.scheduleEvent(event.release());
+ }
+}
+
+void HTMLMediaElementEncryptedMedia::playerDestroyed(HTMLMediaElement& element)
+{
+ HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia::from(element);
+ thisElement.setMediaKeysInternal(element, 0);
+}
+
+blink::WebContentDecryptionModule* HTMLMediaElementEncryptedMedia::contentDecryptionModule(HTMLMediaElement& element)
+{
+ HTMLMediaElementEncryptedMedia& thisElement = HTMLMediaElementEncryptedMedia::from(element);
+ return thisElement.contentDecryptionModule();
+}
+
+} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698