Add Encrypted Media Extensions events and errors to HTMLMediaElement
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Apr 2012 01:32:36 +0000 (01:32 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Apr 2012 01:32:36 +0000 (01:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=82974

Patch by David Dorwin <ddorwin@chromium.org> on 2012-04-12
Reviewed by Adam Barth.

The new events and errors are behind the ENABLE(ENCRYPTED_MEDIA) feature define.
Implementation is based on v0.1 of the draft proposal at
http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html#events.

Source/WebCore:

Tests: fast/events/constructors/media-key-event-constructor.html
       media/encrypted-media/encrypted-media-constants.html
       media/encrypted-media/encrypted-media-events.html

* WebCore.gypi:
* bindings/v8/Dictionary.cpp:
(WebCore::Dictionary::get):
(WebCore):
* bindings/v8/Dictionary.h:
(WebCore):
(Dictionary):
* dom/EventNames.h:
(WebCore):
* dom/EventNames.in:
* html/HTMLAttributeNames.in:
* html/HTMLMediaElement.cpp:
(WebCore):
(WebCore::HTMLMediaElement::mediaPlayerKeyAdded):
(WebCore::HTMLMediaElement::mediaPlayerKeyError):
(WebCore::HTMLMediaElement::mediaPlayerKeyMessage):
(WebCore::HTMLMediaElement::mediaPlayerKeyNeeded):
* html/HTMLMediaElement.h:
(HTMLMediaElement):
* html/HTMLMediaElement.idl:
* html/MediaError.h:
* html/MediaError.idl:
* html/MediaKeyError.h: Added.
(WebCore):
(MediaKeyError):
(WebCore::MediaKeyError::create):
(WebCore::MediaKeyError::code):
(WebCore::MediaKeyError::MediaKeyError):
* html/MediaKeyError.idl: Added.
* html/MediaKeyEvent.cpp: Added.
(WebCore):
(WebCore::MediaKeyEventInit::MediaKeyEventInit):
(WebCore::MediaKeyEvent::MediaKeyEvent):
(WebCore::MediaKeyEvent::~MediaKeyEvent):
(WebCore::MediaKeyEvent::interfaceName):
* html/MediaKeyEvent.h: Added.
(WebCore):
(MediaKeyEventInit):
(MediaKeyEvent):
(WebCore::MediaKeyEvent::create):
(WebCore::MediaKeyEvent::keySystem):
(WebCore::MediaKeyEvent::sessionId):
(WebCore::MediaKeyEvent::initData):
(WebCore::MediaKeyEvent::message):
(WebCore::MediaKeyEvent::defaultURL):
(WebCore::MediaKeyEvent::errorCode):
(WebCore::MediaKeyEvent::systemCode):
* html/MediaKeyEvent.idl: Added.
* page/DOMWindow.idl:
* platform/graphics/MediaPlayer.cpp:
(WebCore):
(WebCore::MediaPlayer::keyAdded):
(WebCore::MediaPlayer::keyError):
(WebCore::MediaPlayer::keyMessage):
(WebCore::MediaPlayer::keyNeeded):
* platform/graphics/MediaPlayer.h:
(MediaPlayerClient):
(WebCore::MediaPlayerClient::mediaPlayerKeyAdded):
(WebCore::MediaPlayerClient::mediaPlayerKeyError):
(WebCore::MediaPlayerClient::mediaPlayerKeyMessage):
(WebCore::MediaPlayerClient::mediaPlayerKeyNeeded):
(MediaPlayer):

Source/WebKit/chromium:

* public/WebMediaPlayerClient.h:
* src/AssertMatchingEnums.cpp:
* src/WebMediaPlayerClientImpl.cpp:
(WebKit::WebMediaPlayerClientImpl::keyAdded):
(WebKit):
(WebKit::WebMediaPlayerClientImpl::keyError):
(WebKit::WebMediaPlayerClientImpl::keyMessage):
(WebKit::WebMediaPlayerClientImpl::keyNeeded):
* src/WebMediaPlayerClientImpl.h:
(WebMediaPlayerClientImpl):

LayoutTests:

* fast/events/constructors/media-key-event-constructor-expected.txt: Added.
* fast/events/constructors/media-key-event-constructor.html: Added.
* fast/js/resources/js-test-pre.js:
(shouldBeZero):
(shouldBeEmptyString):
* media/encrypted-media/encrypted-media-constants-expected.txt: Added.
* media/encrypted-media/encrypted-media-constants.html: Added.
* media/encrypted-media/encrypted-media-events-expected.txt: Added.
* media/encrypted-media/encrypted-media-events.html: Added.
* media/video-test.js:
(testExpected):
(testArraysEqual):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@114067 268f45cc-cd09-0410-ab3c-d52691b4dbfc

34 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/constructors/media-key-event-constructor-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/constructors/media-key-event-constructor.html [new file with mode: 0644]
LayoutTests/fast/js/resources/js-test-pre.js
LayoutTests/media/encrypted-media/encrypted-media-constants-expected.txt [new file with mode: 0644]
LayoutTests/media/encrypted-media/encrypted-media-constants.html [new file with mode: 0644]
LayoutTests/media/encrypted-media/encrypted-media-events-expected.txt [new file with mode: 0644]
LayoutTests/media/encrypted-media/encrypted-media-events.html [new file with mode: 0644]
LayoutTests/media/video-test.js
Source/WebCore/ChangeLog
Source/WebCore/WebCore.gypi
Source/WebCore/bindings/v8/Dictionary.cpp
Source/WebCore/bindings/v8/Dictionary.h
Source/WebCore/dom/EventNames.h
Source/WebCore/dom/EventNames.in
Source/WebCore/html/HTMLAttributeNames.in
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/HTMLMediaElement.idl
Source/WebCore/html/MediaError.h
Source/WebCore/html/MediaError.idl
Source/WebCore/html/MediaKeyError.h [new file with mode: 0644]
Source/WebCore/html/MediaKeyError.idl [new file with mode: 0644]
Source/WebCore/html/MediaKeyEvent.cpp [new file with mode: 0644]
Source/WebCore/html/MediaKeyEvent.h [new file with mode: 0644]
Source/WebCore/html/MediaKeyEvent.idl [new file with mode: 0644]
Source/WebCore/page/DOMWindow.idl
Source/WebCore/platform/graphics/MediaPlayer.cpp
Source/WebCore/platform/graphics/MediaPlayer.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebMediaPlayerClient.h
Source/WebKit/chromium/src/AssertMatchingEnums.cpp
Source/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp
Source/WebKit/chromium/src/WebMediaPlayerClientImpl.h

index 6bbd6f3..dd39561 100644 (file)
@@ -1,3 +1,27 @@
+2012-04-12  David Dorwin  <ddorwin@chromium.org>
+
+        Add Encrypted Media Extensions events and errors to HTMLMediaElement
+        https://bugs.webkit.org/show_bug.cgi?id=82974
+
+        Reviewed by Adam Barth.
+
+        The new events and errors are behind the ENABLE(ENCRYPTED_MEDIA) feature define.
+        Implementation is based on v0.1 of the draft proposal at
+        http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html#events.
+
+        * fast/events/constructors/media-key-event-constructor-expected.txt: Added.
+        * fast/events/constructors/media-key-event-constructor.html: Added.
+        * fast/js/resources/js-test-pre.js:
+        (shouldBeZero):
+        (shouldBeEmptyString):
+        * media/encrypted-media/encrypted-media-constants-expected.txt: Added.
+        * media/encrypted-media/encrypted-media-constants.html: Added.
+        * media/encrypted-media/encrypted-media-events-expected.txt: Added.
+        * media/encrypted-media/encrypted-media-events.html: Added.
+        * media/video-test.js:
+        (testExpected):
+        (testArraysEqual):
+
 2012-04-12  Pablo Flouret  <pablof@motorola.com>
 
         Make layout tests not access apache on localhost:80
diff --git a/LayoutTests/fast/events/constructors/media-key-event-constructor-expected.txt b/LayoutTests/fast/events/constructors/media-key-event-constructor-expected.txt
new file mode 100644 (file)
index 0000000..9b0b7c2
--- /dev/null
@@ -0,0 +1,102 @@
+This tests the constructor for the MediaKeyEvent DOM class.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+*** No initializer passed ***
+PASS new MediaKeyEvent('MediaKeyEvent').bubbles is false
+PASS new MediaKeyEvent('MediaKeyEvent').cancelable is false
+PASS new MediaKeyEvent('MediaKeyEvent').keySystem is ""
+PASS new MediaKeyEvent('MediaKeyEvent').sessionId is ""
+PASS new MediaKeyEvent('MediaKeyEvent').initData is null
+PASS new MediaKeyEvent('MediaKeyEvent').message is null
+PASS new MediaKeyEvent('MediaKeyEvent').defaultURL is ""
+PASS new MediaKeyEvent('MediaKeyEvent').errorCode is null
+PASS new MediaKeyEvent('MediaKeyEvent').systemCode is 0
+
+*** Bubbles and cancelable true, other members are missing ***
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).bubbles is true
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).cancelable is true
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).keySystem is ""
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).sessionId is ""
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).initData is null
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).message is null
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).defaultURL is ""
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).errorCode is null
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).systemCode is 0
+
+*** Bubbles and cancelable true, invalid other members ***
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).bubbles is true
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).cancelable is true
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).keySystem is "undefined"
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).sessionId is "undefined"
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).initData is null
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).message is null
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).defaultURL is "undefined"
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).errorCode is null
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).systemCode is 0
+
+*** Initialize 'keySystem' with a invalid values ***
+PASS new MediaKeyEvent('MediaKeyEvent', { keySystem: emptyObject }).keySystem is "[object Object]"
+PASS new MediaKeyEvent('MediaKeyEvent', { keySystem: document }).keySystem is "[object HTMLDocument]"
+
+*** Initialize 'sessionId' with a invalid values ***
+PASS new MediaKeyEvent('MediaKeyEvent', { sessionId: emptyObject }).sessionId is "[object Object]"
+PASS new MediaKeyEvent('MediaKeyEvent', { sessionId: document }).sessionId is "[object HTMLDocument]"
+
+*** Initialize 'initData' with a invalid values ***
+PASS new MediaKeyEvent('MediaKeyEvent', { initData: 10 }).initData is null
+PASS new MediaKeyEvent('MediaKeyEvent', { initData: 'string' }).initData is null
+PASS new MediaKeyEvent('MediaKeyEvent', { initData: emptyObject }).initData is null
+PASS new MediaKeyEvent('MediaKeyEvent', { initData: document }).initData is null
+
+*** Initialize 'message' with a invalid values ***
+PASS new MediaKeyEvent('MediaKeyEvent', { message: 10 }).message is null
+PASS new MediaKeyEvent('MediaKeyEvent', { message: 'string' }).message is null
+PASS new MediaKeyEvent('MediaKeyEvent', { message: emptyObject }).message is null
+PASS new MediaKeyEvent('MediaKeyEvent', { message: document }).message is null
+
+*** Initialize 'defaultURL' with a invalid values ***
+PASS new MediaKeyEvent('MediaKeyEvent', { defaultURL: emptyObject }).defaultURL is "[object Object]"
+PASS new MediaKeyEvent('MediaKeyEvent', { defaultURL: document }).defaultURL is "[object HTMLDocument]"
+
+*** Initialize 'errorCode' with a invalid values ***
+PASS new MediaKeyEvent('MediaKeyEvent', { errorCode: 10 }).errorCode is null
+PASS new MediaKeyEvent('MediaKeyEvent', { errorCode: 'string' }).errorCode is null
+PASS new MediaKeyEvent('MediaKeyEvent', { errorCode: emptyObject }).errorCode is null
+PASS new MediaKeyEvent('MediaKeyEvent', { errorCode: document }).errorCode is null
+
+*** Initialize 'systemCode' with a invalid values ***
+PASS new MediaKeyEvent('MediaKeyEvent', { systemCode: 'string' }).systemCode is 0
+PASS new MediaKeyEvent('MediaKeyEvent', { systemCode: emptyObject }).systemCode is 0
+PASS new MediaKeyEvent('MediaKeyEvent', { systemCode: document }).systemCode is 0
+
+*** Bubbles and cancelable true, valid other members ***
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).bubbles is true
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).cancelable is true
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).keySystem is "keySystem"
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).sessionId is "sessionId"
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).initData is initDataArray
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).message is messageArray
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).defaultURL is "defaultURL"
+FAIL new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).errorCode should be function MediaKeyError() { [native code] } (of type function). Was null (of type object).
+FAIL new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).errorCode.code should be 1. Threw exception TypeError: Cannot read property 'code' of null
+PASS new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).systemCode is 123
+
+*** Initialize with valid members ***
+FAIL new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).bubbles should be true. Was false.
+FAIL new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).cancelable should be true. Was false.
+PASS new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).keySystem is "keySystem"
+PASS new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).sessionId is "sessionId"
+PASS new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).initData is initDataArray
+PASS new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).message is messageArray
+PASS new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).defaultURL is "defaultURL"
+FAIL new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).errorCode should be function MediaKeyError() { [native code] } (of type function). Was null (of type object).
+FAIL new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).errorCode.code should be 1. Threw exception TypeError: Cannot read property 'code' of null
+PASS new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).systemCode is 123
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/constructors/media-key-event-constructor.html b/LayoutTests/fast/events/constructors/media-key-event-constructor.html
new file mode 100644 (file)
index 0000000..db33a8a
--- /dev/null
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src="../../js/resources/js-test-pre.js"></script>
+</head>
+
+<body>
+    <script>
+
+        window.jsTestIsAsync = true;
+
+        description("This tests the constructor for the MediaKeyEvent DOM class.");
+
+        function test()
+        {
+            debug("<br>*** No initializer passed ***");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent').bubbles", "false");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent').cancelable", "false");
+            shouldBeEmptyString("new MediaKeyEvent('MediaKeyEvent').keySystem");
+            shouldBeEmptyString("new MediaKeyEvent('MediaKeyEvent').sessionId");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent').initData");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent').message");
+            shouldBeEmptyString("new MediaKeyEvent('MediaKeyEvent').defaultURL");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent').errorCode");
+            shouldBeZero("new MediaKeyEvent('MediaKeyEvent').systemCode");
+    
+            debug("<br>*** Bubbles and cancelable true, other members are missing ***");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).bubbles", "true");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).cancelable", "true");
+            shouldBeEmptyString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).keySystem");
+            shouldBeEmptyString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).sessionId");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).initData");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).message");
+            shouldBeEmptyString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).defaultURL");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).errorCode");
+            shouldBeZero("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true }).systemCode");
+    
+            debug("<br>*** Bubbles and cancelable true, invalid other members ***");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).bubbles", "true");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).cancelable", "true");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).keySystem", "undefined");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).sessionId", "undefined");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).initData");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).message");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).defaultURL", "undefined");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).errorCode");
+            shouldBeZero("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: undefined, sessionId: undefined, initData: Uint8Array, message: Uint8Array, defaultURL: undefined, errorCode: MediaKeyError, systemCode: undefined }).systemCode");
+    
+            debug("<br>*** Initialize 'keySystem' with a invalid values ***");
+            emptyObject = { };
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { keySystem: emptyObject }).keySystem", "[object Object]");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { keySystem: document }).keySystem", "[object HTMLDocument]");
+
+            debug("<br>*** Initialize 'sessionId' with a invalid values ***");
+            emptyObject = { };
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { sessionId: emptyObject }).sessionId", "[object Object]");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { sessionId: document }).sessionId", "[object HTMLDocument]");
+
+            debug("<br>*** Initialize 'initData' with a invalid values ***");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { initData: 10 }).initData");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { initData: \'string\' }).initData");
+            emptyObject = { };
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { initData: emptyObject }).initData");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { initData: document }).initData");
+
+            debug("<br>*** Initialize 'message' with a invalid values ***");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { message: 10 }).message");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { message: \'string\' }).message");
+            emptyObject = { };
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { message: emptyObject }).message");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { message: document }).message");
+
+            debug("<br>*** Initialize 'defaultURL' with a invalid values ***");
+            emptyObject = { };
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { defaultURL: emptyObject }).defaultURL", "[object Object]");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { defaultURL: document }).defaultURL", "[object HTMLDocument]");
+
+            debug("<br>*** Initialize 'errorCode' with a invalid values ***");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { errorCode: 10 }).errorCode");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { errorCode: \'string\' }).errorCode");
+            emptyObject = { };
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { errorCode: emptyObject }).errorCode");
+            shouldBeNull("new MediaKeyEvent('MediaKeyEvent', { errorCode: document }).errorCode");
+
+            debug("<br>*** Initialize 'systemCode' with a invalid values ***");
+            shouldBeZero("new MediaKeyEvent('MediaKeyEvent', { systemCode: \'string\' }).systemCode");
+            emptyObject = { };
+            shouldBeZero("new MediaKeyEvent('MediaKeyEvent', { systemCode: emptyObject }).systemCode");
+            shouldBeZero("new MediaKeyEvent('MediaKeyEvent', { systemCode: document }).systemCode");
+
+            debug("<br>*** Bubbles and cancelable true, valid other members ***");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).bubbles", "true");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).cancelable", "true");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).keySystem", "keySystem");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).sessionId", "sessionId");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).initData", "initDataArray");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).message", "messageArray");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).defaultURL", "defaultURL");
+            // FIXME(82988): These two fail.
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).errorCode", "errorObject");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).errorCode.code", "MediaKeyError.MEDIA_KEYERR_UNKNOWN");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { bubbles: true, cancelable: true, keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).systemCode", "123");
+
+            debug("<br>*** Initialize with valid members ***");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).bubbles", "true");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).cancelable", "true");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).keySystem", "keySystem");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).sessionId", "sessionId");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).initData", "initDataArray");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).message", "messageArray");
+            shouldBeEqualToString("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).defaultURL", "defaultURL");
+            // FIXME(82988): These two fail.
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).errorCode", "errorObject");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).errorCode.code", "MediaKeyError.MEDIA_KEYERR_UNKNOWN");
+            shouldBe("new MediaKeyEvent('MediaKeyEvent', { keySystem: 'keySystem', sessionId: 'sessionId', initData: initDataArray, message: messageArray, defaultURL: 'defaultURL', errorCode: errorObject, systemCode: 123 }).systemCode", "123");
+
+            debug("");
+            finishJSTest();
+        }
+
+        var initDataArray = new Uint8Array([0x41, 0x42, 0x43]);
+        var messageArray = new Uint8Array([0x51, 0x52, 0x53]);
+        // FIXME(82988): This does not create an error like we want.
+        var errorObject = window.MediaKeyError;
+        // shouldBe("typeof errorObject", TBD);
+
+        video = document.createElement('video');
+        document.body.appendChild(video);
+
+        test()
+    </script>
+    <script src="../../js/resources/js-test-post.js"></script>
+
+</body>
+</html>
index 036e76a..0aa417d 100644 (file)
@@ -254,6 +254,7 @@ function shouldBeTrueQuiet(_a) { shouldBe(_a, "true", true); }
 function shouldBeFalse(_a) { shouldBe(_a, "false"); }
 function shouldBeNaN(_a) { shouldBe(_a, "NaN"); }
 function shouldBeNull(_a) { shouldBe(_a, "null"); }
+function shouldBeZero(_a) { shouldBe(_a, "0"); }
 
 function shouldBeEqualToString(a, b)
 {
@@ -261,6 +262,8 @@ function shouldBeEqualToString(a, b)
   shouldBe(a, unevaledString);
 }
 
+function shouldBeEmptyString(_a) { shouldBeEqualToString(_a, ""); }
+
 function shouldEvaluateTo(actual, expected) {
   // A general-purpose comparator.  'actual' should be a string to be
   // evaluated, as for shouldBe(). 'expected' may be any type and will be
diff --git a/LayoutTests/media/encrypted-media/encrypted-media-constants-expected.txt b/LayoutTests/media/encrypted-media/encrypted-media-constants-expected.txt
new file mode 100644 (file)
index 0000000..f3940ad
--- /dev/null
@@ -0,0 +1,12 @@
+Test MediaKeyError constants and additional MediaError constant.
+
+EXPECTED (MediaKeyError.MEDIA_KEYERR_UNKNOWN == '1') OK
+EXPECTED (MediaKeyError.MEDIA_KEYERR_CLIENT == '2') OK
+EXPECTED (MediaKeyError.MEDIA_KEYERR_SERVICE == '3') OK
+EXPECTED (MediaKeyError.MEDIA_KEYERR_OUTPUT == '4') OK
+EXPECTED (MediaKeyError.MEDIA_KEYERR_HARDWARECHANGE == '5') OK
+EXPECTED (MediaKeyError.MEDIA_KEYERR_DOMAIN == '6') OK
+
+EXPECTED (MediaError.MEDIA_ERR_ENCRYPTED == '5') OK
+END OF TEST
+
diff --git a/LayoutTests/media/encrypted-media/encrypted-media-constants.html b/LayoutTests/media/encrypted-media/encrypted-media-constants.html
new file mode 100644 (file)
index 0000000..8cb697a
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=../video-test.js></script>
+    <script type="text/javascript">
+        function doTest () 
+        {
+            testExpected("MediaKeyError.MEDIA_KEYERR_UNKNOWN", 1);
+            testExpected("MediaKeyError.MEDIA_KEYERR_CLIENT", 2);
+            testExpected("MediaKeyError.MEDIA_KEYERR_SERVICE", 3);
+            testExpected("MediaKeyError.MEDIA_KEYERR_OUTPUT", 4);
+            testExpected("MediaKeyError.MEDIA_KEYERR_HARDWARECHANGE", 5);
+            testExpected("MediaKeyError.MEDIA_KEYERR_DOMAIN", 6);
+            consoleWrite("");
+
+            testExpected("MediaError.MEDIA_ERR_ENCRYPTED", 5);
+
+            endTest();
+        }
+    </script>
+</head>
+<body onload="doTest()">
+    <p>Test MediaKeyError constants and additional MediaError constant.</p>
+</body>
+</html>
diff --git a/LayoutTests/media/encrypted-media/encrypted-media-events-expected.txt b/LayoutTests/media/encrypted-media/encrypted-media-events-expected.txt
new file mode 100644 (file)
index 0000000..7a84126
--- /dev/null
@@ -0,0 +1,128 @@
+Test all the key-related events.
+
+*** Verify the presence of on* attributes. These would return undefined if they are not present. ***
+EXPECTED (video.onwebkitkeyadded === 'null') OK
+EXPECTED (video.onwebkitkeyerror === 'null') OK
+EXPECTED (video.onwebkitkeymessage === 'null') OK
+EXPECTED (video.onwebkitneedkey === 'null') OK
+
+*** Test events using on* attributes. ***
+EVENT(loadstart)
+
+RUN(video.webkitGenerateKeyRequest('webkit-org.w3.clearkey', initData))
+keymessage event occurred
+EXPECTED (event.target == '[object HTMLVideoElement]') OK
+EXPECTED (event instanceof window.MediaKeyEvent == 'true') OK
+EXPECTED (event.keySystem == 'webkit-org.w3.clearkey') OK
+The sessionId should be a non-empty string containing an integer.
+EXPECTED (event.sessionId != '') OK
+EXPECTED (event.sessionId != 'null') OK
+EXPECTED (event.sessionId != 'undefined') OK
+EXPECTED (isNaN(event.sessionId) == 'false') OK
+EXPECTED (String(event.sessionId) == String(parseInt(event.sessionId)) == 'true') OK
+Implementations should avoid sessionIds of 0.
+EXPECTED (event.sessionId > '0') OK
+EXPECTED (event.initData === 'null') OK
+EXPECTED (event.message.length == '3') OK
+EXPECTED (event.message[0] == '65') OK
+EXPECTED (event.message[1] == '66') OK
+EXPECTED (event.message[2] == '67') OK
+EXPECTED (event.defaultURL == '') OK
+EXPECTED (event.errorCode === 'null') OK
+EXPECTED (event.systemCode == '0') OK
+
+RUN(video.webkitAddKey('webkit-org.w3.clearkey', key, event.initData, event.sessionId))
+keyadded event occurred
+EXPECTED (event.target == '[object HTMLVideoElement]') OK
+EXPECTED (event instanceof window.MediaKeyEvent == 'true') OK
+EXPECTED (event.keySystem == 'webkit-org.w3.clearkey') OK
+EXPECTED (event.sessionId == keyMessageSessionId == 'true') OK
+EXPECTED (event.initData === 'null') OK
+EXPECTED (event.message === 'null') OK
+EXPECTED (event.defaultURL == '') OK
+EXPECTED (event.errorCode === 'null') OK
+EXPECTED (event.systemCode == '0') OK
+
+RUN(video.webkitAddKey('webkit-org.w3.clearkey', invalidKey, null, event.sessionId))
+keyerror event occurred
+EXPECTED (event.target == '[object HTMLVideoElement]') OK
+EXPECTED (event instanceof window.MediaKeyEvent == 'true') OK
+EXPECTED (event.keySystem == 'webkit-org.w3.clearkey') OK
+EXPECTED (event.sessionId == keyMessageSessionId == 'true') OK
+EXPECTED (event.initData === 'null') OK
+EXPECTED (event.message === 'null') OK
+EXPECTED (event.defaultURL == '') OK
+EXPECTED (event.errorCode.code == '1') OK
+EXPECTED (event.systemCode == '0') OK
+
+*** Test events using addEventListener(). ***
+EVENT(loadstart)
+
+RUN(video.webkitGenerateKeyRequest('webkit-org.w3.clearkey', initData))
+EVENT(webkitkeymessage)
+keymessage event occurred
+EXPECTED (event.target == '[object HTMLVideoElement]') OK
+EXPECTED (event instanceof window.MediaKeyEvent == 'true') OK
+EXPECTED (event.keySystem == 'webkit-org.w3.clearkey') OK
+The sessionId should be a non-empty string containing an integer.
+EXPECTED (event.sessionId != '') OK
+EXPECTED (event.sessionId != 'null') OK
+EXPECTED (event.sessionId != 'undefined') OK
+EXPECTED (isNaN(event.sessionId) == 'false') OK
+EXPECTED (String(event.sessionId) == String(parseInt(event.sessionId)) == 'true') OK
+Implementations should avoid sessionIds of 0.
+EXPECTED (event.sessionId > '0') OK
+The sessionsId should be different from the first run.
+EXPECTED (event.sessionId != '1') OK
+EXPECTED (event.initData === 'null') OK
+EXPECTED (event.message.length == '3') OK
+EXPECTED (event.message[0] == '65') OK
+EXPECTED (event.message[1] == '66') OK
+EXPECTED (event.message[2] == '67') OK
+EXPECTED (event.defaultURL == '') OK
+EXPECTED (event.errorCode === 'null') OK
+EXPECTED (event.systemCode == '0') OK
+
+RUN(video.webkitAddKey('webkit-org.w3.clearkey', key, event.initData, event.sessionId))
+EVENT(webkitkeyadded)
+keyadded event occurred
+EXPECTED (event.target == '[object HTMLVideoElement]') OK
+EXPECTED (event instanceof window.MediaKeyEvent == 'true') OK
+EXPECTED (event.keySystem == 'webkit-org.w3.clearkey') OK
+EXPECTED (event.sessionId == keyMessageSessionId == 'true') OK
+EXPECTED (event.initData === 'null') OK
+EXPECTED (event.message === 'null') OK
+EXPECTED (event.defaultURL == '') OK
+EXPECTED (event.errorCode === 'null') OK
+EXPECTED (event.systemCode == '0') OK
+
+RUN(video.webkitAddKey('webkit-org.w3.clearkey', invalidKey, null, event.sessionId))
+EVENT(webkitkeyerror)
+keyerror event occurred
+EXPECTED (event.target == '[object HTMLVideoElement]') OK
+EXPECTED (event instanceof window.MediaKeyEvent == 'true') OK
+EXPECTED (event.keySystem == 'webkit-org.w3.clearkey') OK
+EXPECTED (event.sessionId == keyMessageSessionId == 'true') OK
+EXPECTED (event.initData === 'null') OK
+EXPECTED (event.message === 'null') OK
+EXPECTED (event.defaultURL == '') OK
+EXPECTED (event.errorCode.code == '1') OK
+EXPECTED (event.systemCode == '0') OK
+
+Attributes are read-only.
+RUN(event.keySystem = 'blah')
+RUN(event.sessionId = 'blah')
+RUN(event.initData = new Uint8Array([0x12]))
+RUN(event.message = new Uint8Array([0x12]))
+RUN(event.defaultURL = 'example.com')
+RUN(event.errorCode.code = MediaKeyError.MEDIA_KEYERR_CLIENT)
+RUN(event.systemCode = 123)
+EXPECTED (event.keySystem == 'webkit-org.w3.clearkey') OK
+EXPECTED (event.sessionId == keyMessageSessionId == 'true') OK
+EXPECTED (event.initData === 'null') OK
+EXPECTED (event.message === 'null') OK
+EXPECTED (event.defaultURL == '') OK
+EXPECTED (event.errorCode.code == '1') OK
+EXPECTED (event.systemCode == '0') OK
+END OF TEST
+
diff --git a/LayoutTests/media/encrypted-media/encrypted-media-events.html b/LayoutTests/media/encrypted-media/encrypted-media-events.html
new file mode 100644 (file)
index 0000000..9c43035
--- /dev/null
@@ -0,0 +1,197 @@
+<!doctype html>
+<html lang="en">
+    <head>
+    </head>
+    <body>
+        <video></video>
+        <p>Test all the key-related events.</p>
+
+        <script src=../media-file.js></script>
+        <script src=../video-test.js></script>
+        <script>
+            // The test runs twice, once using on* and then using addEventListener().
+            var isFirstRun = true;
+
+            var initData = new Uint8Array([0x41, 0x42, 0x43]);
+            // 128 bit key.
+            var key = new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+                                      0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70]);
+            // This key will cause an asynchronous error because it is too short.
+            var invalidKey = new Uint8Array([0x61]);
+
+            // After the first keyMessage event, the sessionId should always be the same.
+            // Initialize it to an invalid value until then.
+            var keyMessageSessionId = -1;
+            // Remember the first ID to make sure the second one is different.
+            var firstRunKeyMessageSessionId = -1;
+
+            function keyAdded(event)
+            {
+                consoleWrite("keyadded event occurred");
+
+                testExpected("event.target", video);
+                testExpected("event instanceof window.MediaKeyEvent", true);
+
+                testExpected("event.keySystem", "webkit-org.w3.clearkey");
+                testExpected("event.sessionId == keyMessageSessionId", true);
+                // The other attributes are not used for this event.
+                testExpected("event.initData", null, "===");
+                testExpected("event.message", null, "===");
+                testExpected("event.defaultURL", "");
+                testExpected("event.errorCode", null, "===");
+                testExpected("event.systemCode", 0);
+
+                consoleWrite("");
+                // Cause a keyerror by passing an invalid key.
+                run("video.webkitAddKey('webkit-org.w3.clearkey', invalidKey, null, event.sessionId)");
+            }
+
+            function keyError(event)
+            {
+                consoleWrite("keyerror event occurred");
+
+                testExpected("event.target", video);
+                testExpected("event instanceof window.MediaKeyEvent", true);
+
+                testExpected("event.keySystem", "webkit-org.w3.clearkey");
+                testExpected("event.sessionId == keyMessageSessionId", true);
+                // The next three attributes are not used for this event.
+                testExpected("event.initData", null, "===");
+                testExpected("event.message", null, "===");
+                testExpected("event.defaultURL", "");
+                testExpected("event.errorCode.code", MediaKeyError.MEDIA_KEYERR_UNKNOWN);
+                // systemCode is not supported by the Clear Key key system.
+                testExpected("event.systemCode", 0);
+
+                if (isFirstRun) {
+                    isFirstRun = false;
+                    runTest();
+                } else {
+                    consoleWrite("");
+                    consoleWrite("Attributes are read-only.");
+                    run("event.keySystem = 'blah'");
+                    run("event.sessionId = 'blah'");
+                    run("event.initData = new Uint8Array([0x12])");
+                    run("event.message  = new Uint8Array([0x12])");
+                    run("event.defaultURL = 'example.com'");
+                    run("event.errorCode.code = MediaKeyError.MEDIA_KEYERR_CLIENT");
+                    run("event.systemCode = 123");
+
+                    testExpected("event.keySystem", "webkit-org.w3.clearkey");
+                    testExpected("event.sessionId == keyMessageSessionId", true);
+                    testExpected("event.initData", null, "===");
+                    testExpected("event.message", null, "===");
+                    testExpected("event.defaultURL", "");
+                    testExpected("event.errorCode.code", MediaKeyError.MEDIA_KEYERR_UNKNOWN);
+                    testExpected("event.systemCode", 0);
+
+                    endTest();
+                }
+            }
+
+            function keyMessage(event)
+            {
+                consoleWrite("keymessage event occurred");
+
+                testExpected("event.target", video);
+                testExpected("event instanceof window.MediaKeyEvent", true);
+
+                testExpected("event.keySystem", "webkit-org.w3.clearkey");
+
+                consoleWrite("The sessionId should be a non-empty string containing an integer.");
+                testExpected("event.sessionId", "", "!=");
+                testExpected("event.sessionId", null, "!=");
+                testExpected("event.sessionId", undefined, "!=");
+                testExpected("isNaN(event.sessionId)", false);
+                // Make sure the number is not a float.
+                testExpected("String(event.sessionId) == String(parseInt(event.sessionId))", true);
+                consoleWrite("Implementations should avoid sessionIds of 0.");
+                testExpected("event.sessionId", 0, ">");
+                // All other events should have this same sessionId.
+                keyMessageSessionId = event.sessionId;
+                if (isFirstRun)
+                    firstRunKeyMessageSessionId = keyMessageSessionId;
+                else {
+                    consoleWrite("The sessionsId should be different from the first run.");
+                    testExpected("event.sessionId", firstRunKeyMessageSessionId, "!=");
+                }
+
+                // initData is not used for this event.
+                testExpected("event.initData", null, "===");
+                // At least for now, the Clear Key message is the initData.
+                testArraysEqual("event.message", initData);
+                // Not supported by the test file.
+                testExpected("event.defaultURL", "");
+                // The error attributes are not used for this event.
+                testExpected("event.errorCode", null, "===");
+                testExpected("event.systemCode", 0);
+
+                consoleWrite("");
+                run("video.webkitAddKey('webkit-org.w3.clearkey', key, event.initData, event.sessionId)");
+            }
+
+            function needKey(event)
+            {
+                consoleWrite("needKey event occurred");
+
+                testExpected("event.target", video);
+                testExpected("event instanceof window.MediaKeyEvent", true);
+
+                testExpected("event.keySystem", "webkit-org.w3.clearkey");
+                testExpected("event.sessionId", "");
+                testArraysEqual("event.initData", initData);
+                // The other attributes are not used for this event.
+                testExpected("event.message", null, "===");
+                testExpected("event.defaultURL", "");
+                testExpected("event.errorCode", null, "===");
+                testExpected("event.systemCode", 0);
+
+                consoleWrite("");
+                run("video.webkitGenerateKeyRequest('webkit-org.w3.clearkey', initData)");
+            }
+
+            function runTest()
+            {
+                consoleWrite("");
+                if (isFirstRun) {
+                    consoleWrite("*** Test events using on* attributes. ***");
+                    video.onwebkitkeyadded=keyAdded;
+                    video.onwebkitkeyerror=keyError;
+                    video.onwebkitkeymessage=keyMessage;
+                    video.onwebkitneedkey=needKey;
+                } else {
+                    consoleWrite("*** Test events using addEventListener(). ***");
+
+                    // Clear the on* handlers.
+                    video.onwebkitkeyadded=null;
+                    video.onwebkitkeyerror=null;
+                    video.onwebkitkeymessage=null;
+                    video.onwebkitneedkey=null;
+
+                    waitForEvent('webkitkeyadded', keyAdded);
+                    waitForEvent('webkitkeyerror', keyError);
+                    waitForEvent('webkitkeymessage', keyMessage);
+                    waitForEvent('webkitneedkey', needKey);
+                }
+    
+                // FIXME(82952): Temproary until we have a "test-encrypted" file that causes the needKey event.
+                waitForEventOnce('loadstart',
+                            function() {
+                                consoleWrite("");
+                                run("video.webkitGenerateKeyRequest('webkit-org.w3.clearkey', initData)");
+                            });
+
+                video.setAttribute("src", findMediaFile("video", "../content/test"));
+            }
+
+            consoleWrite("*** Verify the presence of on* attributes. These would return undefined if they are not present. ***");
+            testExpected("video.onwebkitkeyadded", null, "===");
+            testExpected("video.onwebkitkeyerror", null, "===");
+            testExpected("video.onwebkitkeymessage", null, "===");
+            testExpected("video.onwebkitneedkey", null, "===");
+
+            runTest();
+
+        </script>
+    </body>
+</html>
index ebf0f43..06ff623 100644 (file)
@@ -79,11 +79,29 @@ function testExpected(testFuncString, expected, comparison)
         case '>=': success = observed >= expected; break;
         case '!=':  success = observed != expected; break;
         case '==': success = observed == expected; break;
+        case '===': success = observed === expected; break;
     }
 
     reportExpected(success, testFuncString, comparison, expected, observed)
 }
 
+function testArraysEqual(testFuncString, expected)
+{
+    var observed;
+    try {
+        observed = eval(testFuncString);
+    } catch (ex) {
+        consoleWrite(ex);
+        return;
+    }
+  
+    testExpected(testFuncString + ".length", expected.length);
+
+    for (var i = 0; i < observed.length; i++) {
+        testExpected(testFuncString + "[" + i + "]", expected[i]);
+    }
+}
+
 var testNumber = 0;
 
 function reportExpected(success, testFuncString, comparison, expected, observed)
index 4846271..6bc9dfc 100644 (file)
@@ -1,3 +1,81 @@
+2012-04-12  David Dorwin  <ddorwin@chromium.org>
+
+        Add Encrypted Media Extensions events and errors to HTMLMediaElement
+        https://bugs.webkit.org/show_bug.cgi?id=82974
+
+        Reviewed by Adam Barth.
+
+        The new events and errors are behind the ENABLE(ENCRYPTED_MEDIA) feature define.
+        Implementation is based on v0.1 of the draft proposal at
+        http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html#events.
+
+        Tests: fast/events/constructors/media-key-event-constructor.html
+               media/encrypted-media/encrypted-media-constants.html
+               media/encrypted-media/encrypted-media-events.html
+
+        * WebCore.gypi:
+        * bindings/v8/Dictionary.cpp:
+        (WebCore::Dictionary::get):
+        (WebCore):
+        * bindings/v8/Dictionary.h:
+        (WebCore):
+        (Dictionary):
+        * dom/EventNames.h:
+        (WebCore):
+        * dom/EventNames.in:
+        * html/HTMLAttributeNames.in:
+        * html/HTMLMediaElement.cpp:
+        (WebCore):
+        (WebCore::HTMLMediaElement::mediaPlayerKeyAdded):
+        (WebCore::HTMLMediaElement::mediaPlayerKeyError):
+        (WebCore::HTMLMediaElement::mediaPlayerKeyMessage):
+        (WebCore::HTMLMediaElement::mediaPlayerKeyNeeded):
+        * html/HTMLMediaElement.h:
+        (HTMLMediaElement):
+        * html/HTMLMediaElement.idl:
+        * html/MediaError.h:
+        * html/MediaError.idl:
+        * html/MediaKeyError.h: Added.
+        (WebCore):
+        (MediaKeyError):
+        (WebCore::MediaKeyError::create):
+        (WebCore::MediaKeyError::code):
+        (WebCore::MediaKeyError::MediaKeyError):
+        * html/MediaKeyError.idl: Added.
+        * html/MediaKeyEvent.cpp: Added.
+        (WebCore):
+        (WebCore::MediaKeyEventInit::MediaKeyEventInit):
+        (WebCore::MediaKeyEvent::MediaKeyEvent):
+        (WebCore::MediaKeyEvent::~MediaKeyEvent):
+        (WebCore::MediaKeyEvent::interfaceName):
+        * html/MediaKeyEvent.h: Added.
+        (WebCore):
+        (MediaKeyEventInit):
+        (MediaKeyEvent):
+        (WebCore::MediaKeyEvent::create):
+        (WebCore::MediaKeyEvent::keySystem):
+        (WebCore::MediaKeyEvent::sessionId):
+        (WebCore::MediaKeyEvent::initData):
+        (WebCore::MediaKeyEvent::message):
+        (WebCore::MediaKeyEvent::defaultURL):
+        (WebCore::MediaKeyEvent::errorCode):
+        (WebCore::MediaKeyEvent::systemCode):
+        * html/MediaKeyEvent.idl: Added.
+        * page/DOMWindow.idl:
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore):
+        (WebCore::MediaPlayer::keyAdded):
+        (WebCore::MediaPlayer::keyError):
+        (WebCore::MediaPlayer::keyMessage):
+        (WebCore::MediaPlayer::keyNeeded):
+        * platform/graphics/MediaPlayer.h:
+        (MediaPlayerClient):
+        (WebCore::MediaPlayerClient::mediaPlayerKeyAdded):
+        (WebCore::MediaPlayerClient::mediaPlayerKeyError):
+        (WebCore::MediaPlayerClient::mediaPlayerKeyMessage):
+        (WebCore::MediaPlayerClient::mediaPlayerKeyNeeded):
+        (MediaPlayer):
+
 2012-04-12  Anders Carlsson  <andersca@apple.com>
 
         Reset the user preferred language overrides in Internals::reset
index 674cb4d..2f544f3 100644 (file)
             'html/ImageData.idl',
             'html/MediaController.idl',
             'html/MediaError.idl',
+            'html/MediaKeyError.idl',
+            'html/MediaKeyEvent.idl',
             'html/TextMetrics.idl',
             'html/TimeRanges.idl',
             'html/ValidityState.idl',
             'html/MediaError.h',
             'html/MediaFragmentURIParser.cpp',
             'html/MediaFragmentURIParser.h',
+            'html/MediaKeyError.h',
+            'html/MediaKeyEvent.cpp',
+            'html/MediaKeyEvent.h',
             'html/MicroDataItemValue.cpp',
             'html/MicroDataItemValue.h',
             'html/MonthInputType.cpp',
             '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMathMLElementWrapperFactory.h',
             '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaError.cpp',
             '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaError.h',
+            '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaKeyError.cpp',
+            '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaKeyError.h',
+            '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaKeyEvent.cpp',
+            '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaKeyEvent.h',
             '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaList.cpp',
             '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaList.h',
             '<(PRODUCT_DIR)/DerivedSources/WebCore/JSMediaQueryList.cpp',
index c29f96a..fd4da1f 100644 (file)
@@ -30,6 +30,7 @@
 #include "V8Binding.h"
 #include "V8DOMWindow.h"
 #include "V8Storage.h"
+#include "V8Uint8Array.h"
 #include "V8Utilities.h"
 #include <wtf/MathExtras.h>
 
 #include "V8IDBKeyRange.h"
 #endif
 
+#if ENABLE(ENCRYPTED_MEDIA)
+#include "V8MediaKeyError.h"
+#endif
+
 #if ENABLE(VIDEO_TRACK)
 #include "TrackBase.h"
 #include "V8TextTrack.h"
@@ -293,6 +298,44 @@ bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) c
     return true;
 }
 
+bool Dictionary::get(const String& key, RefPtr<Uint8Array>& value) const
+{
+    v8::Local<v8::Value> v8Value;
+    if (!getKey(key, v8Value))
+        return false;
+
+    Uint8Array* source = 0;
+    if (v8Value->IsObject()) {
+        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
+
+        v8::Handle<v8::Object> array = V8DOMWrapper::lookupDOMWrapper(V8Uint8Array::GetTemplate(), wrapper);
+        if (!array.IsEmpty())
+            source = V8Uint8Array::toNative(array);
+    }
+    value = source;
+    return true;
+}
+
+#if ENABLE(ENCRYPTED_MEDIA)
+bool Dictionary::get(const String& key, RefPtr<MediaKeyError>& value) const
+{
+    v8::Local<v8::Value> v8Value;
+    if (!getKey(key, v8Value))
+        return false;
+
+    MediaKeyError* source = 0;
+    if (v8Value->IsObject()) {
+        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
+
+        v8::Handle<v8::Object> error = V8DOMWrapper::lookupDOMWrapper(V8MediaKeyError::GetTemplate(), wrapper);
+        if (!error.IsEmpty())
+            source = V8MediaKeyError::toNative(error);
+    }
+    value = source;
+    return true;
+}
+#endif
+
 #if ENABLE(VIDEO_TRACK)
 bool Dictionary::get(const String& key, RefPtr<TrackBase>& value) const
 {
index 26c4a6b..32164b8 100644 (file)
@@ -39,6 +39,7 @@ class DOMStringList;
 class DOMWindow;
 class IDBKeyRange;
 class Storage;
+class MediaKeyError;
 class TrackBase;
 class SpeechRecognitionError;
 class SpeechRecognitionResult;
@@ -67,6 +68,10 @@ public:
     bool get(const String&, RefPtr<DOMWindow>&) const;
     bool get(const String&, RefPtr<Storage>&) const;
     bool get(const String&, MessagePortArray&) const;
+    bool get(const String&, RefPtr<Uint8Array>&) const;
+#if ENABLE(ENCRYPTED_MEDIA)
+    bool get(const String&, RefPtr<MediaKeyError>&) const;
+#endif
 #if ENABLE(VIDEO_TRACK)
     bool get(const String&, RefPtr<TrackBase>&) const;
 #endif
index a65a52c..205a8c9 100644 (file)
@@ -161,6 +161,11 @@ namespace WebCore {
     macro(webkitsourceended) \
     macro(webkitsourceclose) \
     \
+    macro(webkitkeyadded) \
+    macro(webkitkeyerror) \
+    macro(webkitkeymessage) \
+    macro(webkitneedkey) \
+    \
     macro(progress) \
     macro(stalled) \
     macro(suspend) \
index d866112..d5a8d99 100644 (file)
@@ -42,4 +42,5 @@ TouchEvent conditional=TOUCH_EVENTS, runtimeConditional=touchEnabled
 DeviceMotionEvent conditional=DEVICE_ORIENTATION
 DeviceOrientationEvent conditional=DEVICE_ORIENTATION
 OrientationEvent interfaceName=Event, conditional=ORIENTATION_EVENTS
+MediaKeyEvent conditional=ENCRYPTED_MEDIA
 TrackEvent conditional=VIDEO_TRACK
index 3c730bb..ba10487 100644 (file)
@@ -247,6 +247,10 @@ onwebkitbeginfullscreen
 onwebkitendfullscreen
 onwebkitfullscreenchange
 onwebkitfullscreenerror
+onwebkitkeyadded
+onwebkitkeyerror
+onwebkitkeymessage
+onwebkitneedkey
 onwebkittransitionend
 open
 optimum
index 0214dd2..a7abe65 100644 (file)
@@ -58,6 +58,8 @@
 #include "MediaDocument.h"
 #include "MediaError.h"
 #include "MediaFragmentURIParser.h"
+#include "MediaKeyError.h"
+#include "MediaKeyEvent.h"
 #include "MediaList.h"
 #include "MediaPlayer.h"
 #include "MediaQueryEvaluator.h"
@@ -1687,6 +1689,86 @@ String HTMLMediaElement::mediaPlayerSourceURL() const
 }
 #endif
 
+#if ENABLE(ENCRYPTED_MEDIA)
+void HTMLMediaElement::mediaPlayerKeyAdded(MediaPlayer*, const String& keySystem, const String& sessionId)
+{
+    MediaKeyEventInit initializer;
+    initializer.keySystem = keySystem;
+    initializer.sessionId = sessionId;
+    initializer.bubbles = false;
+    initializer.cancelable = false;
+
+    RefPtr<Event> event = MediaKeyEvent::create(eventNames().webkitkeyaddedEvent, initializer);
+    event->setTarget(this);
+    m_asyncEventQueue->enqueueEvent(event.release());
+}
+
+void HTMLMediaElement::mediaPlayerKeyError(MediaPlayer*, const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode errorCode, unsigned short systemCode)
+{
+    MediaKeyError::Code mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
+    switch (errorCode) {
+    case MediaPlayerClient::UnknownError:
+        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
+        break;
+    case MediaPlayerClient::ClientError:
+        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_CLIENT;
+        break;
+    case MediaPlayerClient::ServiceError:
+        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_SERVICE;
+        break;
+    case MediaPlayerClient::OutputError:
+        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_OUTPUT;
+        break;
+    case MediaPlayerClient::HardwareChangeError:
+        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_HARDWARECHANGE;
+        break;
+    case MediaPlayerClient::DomainError:
+        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(eventNames().webkitkeyerrorEvent, initializer);
+    event->setTarget(this);
+    m_asyncEventQueue->enqueueEvent(event.release());
+}
+
+void HTMLMediaElement::mediaPlayerKeyMessage(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength)
+{
+    MediaKeyEventInit initializer;
+    initializer.keySystem = keySystem;
+    initializer.sessionId = sessionId;
+    initializer.message = Uint8Array::create(message, messageLength);
+    initializer.bubbles = false;
+    initializer.cancelable = false;
+
+    RefPtr<Event> event = MediaKeyEvent::create(eventNames().webkitkeymessageEvent, initializer);
+    event->setTarget(this);
+    m_asyncEventQueue->enqueueEvent(event.release());
+}
+
+void HTMLMediaElement::mediaPlayerKeyNeeded(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength)
+{
+    MediaKeyEventInit initializer;
+    initializer.keySystem = keySystem;
+    initializer.sessionId = sessionId;
+    initializer.initData = Uint8Array::create(initData, initDataLength);
+    initializer.bubbles = false;
+    initializer.cancelable = false;
+
+    RefPtr<Event> event = MediaKeyEvent::create(eventNames().webkitneedkeyEvent, initializer);
+    event->setTarget(this);
+    m_asyncEventQueue->enqueueEvent(event.release());
+}
+#endif
+
 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
 {
     ASSERT(m_player);
index e65b798..03ace28 100644 (file)
@@ -186,6 +186,11 @@ public:
     void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionCode&);
     void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionCode&);
     void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionCode&);
+
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyadded);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyerror);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeymessage);
+    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitneedkey);
 #endif
 
 // controls
@@ -261,6 +266,13 @@ public:
     void updateWidget(PluginCreationOption);
 #endif
 
+    // EventTarget function.
+    // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
+    // causes an ambiguity error at compile time. This class's constructor
+    // ensures that both implementations return document, so return the result
+    // of one of them here.
+    virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE { return HTMLElement::scriptExecutionContext(); }
+
     bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
     
     bool isFullscreen() const;
@@ -397,6 +409,13 @@ private:
     virtual String mediaPlayerSourceURL() const;
 #endif
 
+#if ENABLE(ENCRYPTED_MEDIA)
+    virtual void mediaPlayerKeyAdded(MediaPlayer*, const String& keySystem, const String& sessionId) OVERRIDE;
+    virtual void mediaPlayerKeyError(MediaPlayer*, const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode) OVERRIDE;
+    virtual void mediaPlayerKeyMessage(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength) OVERRIDE;
+    virtual void mediaPlayerKeyNeeded(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) OVERRIDE;
+#endif
+
     virtual String mediaPlayerReferrer() const OVERRIDE;
     virtual String mediaPlayerUserAgent() const OVERRIDE;
 
index b27a6e9..87854be 100644 (file)
@@ -122,6 +122,11 @@ module html {
         raises (DOMException);
     [V8EnabledAtRuntime=encryptedMedia] void webkitCancelKeyRequest(in [TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, in [Optional=DefaultIsNullString] DOMString sessionId)
         raises (DOMException);
+
+    attribute [V8EnabledAtRuntime=encryptedMedia] EventListener onwebkitkeyadded;
+    attribute [V8EnabledAtRuntime=encryptedMedia] EventListener onwebkitkeyerror;
+    attribute [V8EnabledAtRuntime=encryptedMedia] EventListener onwebkitkeymessage;
+    attribute [V8EnabledAtRuntime=encryptedMedia] EventListener onwebkitneedkey;
 #endif
 
 #if defined(ENABLE_VIDEO_TRACK) && ENABLE_VIDEO_TRACK
index b68c370..90f447f 100644 (file)
@@ -35,7 +35,15 @@ namespace WebCore {
 
 class MediaError : public RefCounted<MediaError> {
 public:
-    enum Code { MEDIA_ERR_ABORTED = 1, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE, MEDIA_ERR_SRC_NOT_SUPPORTED };
+    enum Code {
+        MEDIA_ERR_ABORTED = 1,
+        MEDIA_ERR_NETWORK,
+        MEDIA_ERR_DECODE,
+        MEDIA_ERR_SRC_NOT_SUPPORTED
+#if ENABLE(ENCRYPTED_MEDIA)
+        , MEDIA_ERR_ENCRYPTED
+#endif
+    };
 
     static PassRefPtr<MediaError> create(Code code) { return adoptRef(new MediaError(code)); }
 
index fceb1f5..8eb9d54 100644 (file)
@@ -31,6 +31,9 @@ module html {
           const unsigned short MEDIA_ERR_NETWORK = 2;
           const unsigned short MEDIA_ERR_DECODE = 3;
           const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
+#if defined(ENABLE_ENCRYPTED_MEDIA) && ENABLE_ENCRYPTED_MEDIA
+          const unsigned short MEDIA_ERR_ENCRYPTED = 5;
+#endif
           readonly attribute unsigned short code;
     };
 }
diff --git a/Source/WebCore/html/MediaKeyError.h b/Source/WebCore/html/MediaKeyError.h
new file mode 100644 (file)
index 0000000..12c736d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 Google Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MediaKeyError_h
+#define MediaKeyError_h
+
+#if ENABLE(ENCRYPTED_MEDIA)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class MediaKeyError : public RefCounted<MediaKeyError> {
+public:
+    enum Code {
+        MEDIA_KEYERR_UNKNOWN = 1,
+        MEDIA_KEYERR_CLIENT,
+        MEDIA_KEYERR_SERVICE,
+        MEDIA_KEYERR_OUTPUT,
+        MEDIA_KEYERR_HARDWARECHANGE,
+        MEDIA_KEYERR_DOMAIN
+    };
+
+    static PassRefPtr<MediaKeyError> create(Code code) { return adoptRef(new MediaKeyError(code)); }
+
+    Code code() const { return m_code; }
+
+private:
+    explicit MediaKeyError(Code code) : m_code(code) { }
+
+    Code m_code;
+};
+
+} // namespace WebCore
+
+#endif
+#endif
diff --git a/Source/WebCore/html/MediaKeyError.idl b/Source/WebCore/html/MediaKeyError.idl
new file mode 100644 (file)
index 0000000..55b9b04
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 Google Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+module html {
+    interface [
+        Conditional=ENCRYPTED_MEDIA,
+        V8EnabledAtRuntime=encryptedMedia, 
+    ] MediaKeyError {
+        const unsigned short MEDIA_KEYERR_UNKNOWN = 1;
+        const unsigned short MEDIA_KEYERR_CLIENT = 2;
+        const unsigned short MEDIA_KEYERR_SERVICE = 3;
+        const unsigned short MEDIA_KEYERR_OUTPUT = 4;
+        const unsigned short MEDIA_KEYERR_HARDWARECHANGE = 5;
+        const unsigned short MEDIA_KEYERR_DOMAIN = 6;
+        readonly attribute unsigned short code;
+    };
+}
diff --git a/Source/WebCore/html/MediaKeyEvent.cpp b/Source/WebCore/html/MediaKeyEvent.cpp
new file mode 100644 (file)
index 0000000..2f62dbc
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 Google Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#if ENABLE(ENCRYPTED_MEDIA)
+
+#include "MediaKeyEvent.h"
+
+#include "EventNames.h"
+#include <wtf/Uint8Array.h>
+
+namespace WebCore {
+
+MediaKeyEventInit::MediaKeyEventInit()
+    : systemCode(0)
+{
+}
+
+MediaKeyEvent::MediaKeyEvent()
+{
+}
+
+MediaKeyEvent::MediaKeyEvent(const AtomicString& type, const MediaKeyEventInit& initializer)
+    : Event(type, initializer)
+    , m_keySystem(initializer.keySystem)
+    , m_sessionId(initializer.sessionId)
+    , m_initData(initializer.initData)
+    , m_message(initializer.message)
+    , m_defaultURL(initializer.defaultURL)
+    , m_errorCode(initializer.errorCode)
+    , m_systemCode(initializer.systemCode)
+{
+}
+
+MediaKeyEvent::~MediaKeyEvent()
+{
+}
+
+const AtomicString& MediaKeyEvent::interfaceName() const
+{
+    return eventNames().interfaceForMediaKeyEvent;
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/html/MediaKeyEvent.h b/Source/WebCore/html/MediaKeyEvent.h
new file mode 100644 (file)
index 0000000..3b0d663
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 Google Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MediaKeyEvent_h
+#define MediaKeyEvent_h
+
+#if ENABLE(ENCRYPTED_MEDIA)
+
+#include "Event.h"
+#include "MediaKeyError.h"
+
+namespace WebCore {
+
+struct MediaKeyEventInit : public EventInit {
+    MediaKeyEventInit();
+
+    String keySystem;
+    String sessionId;
+    RefPtr<Uint8Array> initData;
+    RefPtr<Uint8Array> message;
+    String defaultURL;
+    RefPtr<MediaKeyError> errorCode;
+    unsigned short systemCode;
+};
+
+class MediaKeyEvent : public Event {
+public:
+    virtual ~MediaKeyEvent();
+
+    static PassRefPtr<MediaKeyEvent> create()
+    {
+        return adoptRef(new MediaKeyEvent);
+    }
+
+    static PassRefPtr<MediaKeyEvent> create(const AtomicString& type, const MediaKeyEventInit& initializer)
+    {
+        return adoptRef(new MediaKeyEvent(type, initializer));
+    }
+
+    virtual const AtomicString& interfaceName() const;
+
+    String keySystem() const { return m_keySystem; }
+    String sessionId() const { return m_sessionId; }
+    Uint8Array* initData() const { return m_initData.get(); }
+    Uint8Array* message() const { return m_message.get(); }
+    String defaultURL() const { return m_defaultURL; }
+    MediaKeyError* errorCode() const { return m_errorCode.get(); }
+    unsigned short systemCode() const { return m_systemCode; }
+
+private:
+    MediaKeyEvent();
+    MediaKeyEvent(const AtomicString& type, const MediaKeyEventInit& initializer);
+
+    String m_keySystem;
+    String m_sessionId;
+    RefPtr<Uint8Array> m_initData;
+    RefPtr<Uint8Array> m_message;
+    String m_defaultURL;
+    RefPtr<MediaKeyError> m_errorCode;
+    unsigned short m_systemCode;
+};
+
+} // namespace WebCore
+
+#endif
+#endif
diff --git a/Source/WebCore/html/MediaKeyEvent.idl b/Source/WebCore/html/MediaKeyEvent.idl
new file mode 100644 (file)
index 0000000..b1387dc
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 Google Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+module html {
+
+    interface [
+        Conditional=ENCRYPTED_MEDIA,
+        V8EnabledAtRuntime=encryptedMedia,
+        ConstructorTemplate=Event 
+    ] MediaKeyEvent : Event {
+        readonly attribute [InitializedByEventConstructor] DOMString keySystem;
+        readonly attribute [InitializedByEventConstructor] DOMString sessionId;
+        readonly attribute [InitializedByEventConstructor] Uint8Array initData;
+        readonly attribute [InitializedByEventConstructor] Uint8Array message;
+        readonly attribute [InitializedByEventConstructor] DOMString defaultURL;
+        readonly attribute [InitializedByEventConstructor] MediaKeyError errorCode;
+        readonly attribute [InitializedByEventConstructor] unsigned short systemCode;
+    };
+
+}
index 4cb9067..deaf890 100644 (file)
@@ -466,6 +466,9 @@ module window {
         attribute [JSCustomGetter, CustomConstructor] HTMLImageElementConstructorConstructor Image; // Usable with new operator
         attribute [JSCustomGetter] HTMLOptionElementConstructorConstructor Option; // Usable with new operator
 
+        attribute [Conditional=ENCRYPTED_MEDIA, V8EnabledAtRuntime=encryptedMedia] MediaKeyErrorConstructor MediaKeyError;
+        attribute [Conditional=ENCRYPTED_MEDIA, V8EnabledAtRuntime=encryptedMedia] MediaKeyEventConstructor MediaKeyEvent;
+
         attribute [Conditional=VIDEO_TRACK, V8EnabledAtRuntime=webkitVideoTrack] HTMLTrackElementConstructor HTMLTrackElement;
         attribute [Conditional=VIDEO_TRACK, V8EnabledAtRuntime=webkitVideoTrack] TextTrackConstructor TextTrack;
         attribute [Conditional=VIDEO_TRACK, V8EnabledAtRuntime=webkitVideoTrack] TextTrackCueConstructor TextTrackCue; // Usable with the new operator
index 9d6047d..e98ebfd 100644 (file)
@@ -969,7 +969,33 @@ AudioSourceProvider* MediaPlayer::audioSourceProvider()
     return m_private->audioSourceProvider();
 }
 #endif // WEB_AUDIO
-    
+
+#if ENABLE(ENCRYPTED_MEDIA)
+void MediaPlayer::keyAdded(const String& keySystem, const String& sessionId)
+{
+    if (m_mediaPlayerClient)
+        m_mediaPlayerClient->mediaPlayerKeyAdded(this, keySystem, sessionId);
+}
+
+void MediaPlayer::keyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode errorCode, unsigned short systemCode)
+{
+    if (m_mediaPlayerClient)
+        m_mediaPlayerClient->mediaPlayerKeyError(this, keySystem, sessionId, errorCode, systemCode);
+}
+
+void MediaPlayer::keyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength)
+{
+    if (m_mediaPlayerClient)
+        m_mediaPlayerClient->mediaPlayerKeyMessage(this, keySystem, sessionId, message, messageLength);
+}
+
+void MediaPlayer::keyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength)
+{
+    if (m_mediaPlayerClient)
+        m_mediaPlayerClient->mediaPlayerKeyNeeded(this, keySystem, sessionId, initData, initDataLength);
+}
+#endif
+
 String MediaPlayer::referrer() const
 {
     if (!m_mediaPlayerClient)
index 1513afb..d9b6e27 100644 (file)
@@ -168,6 +168,14 @@ public:
     virtual String mediaPlayerSourceURL() const { return "x-media-source-unsupported:"; }
 #endif
 
+#if ENABLE(ENCRYPTED_MEDIA)
+    enum MediaKeyErrorCode { UnknownError = 1, ClientError, ServiceError, OutputError, HardwareChangeError, DomainError };
+    virtual void mediaPlayerKeyAdded(MediaPlayer*, const String& keySystem, const String& sessionId) { }
+    virtual void mediaPlayerKeyError(MediaPlayer*, const String& keySystem, const String& sessionId, MediaKeyErrorCode errorCode, unsigned short systemCode) { }
+    virtual void mediaPlayerKeyMessage(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength) { }
+    virtual void mediaPlayerKeyNeeded(MediaPlayer*, const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) { }
+#endif
+
     virtual String mediaPlayerReferrer() const { return String(); }
     virtual String mediaPlayerUserAgent() const { return String(); }
 };
@@ -346,6 +354,13 @@ public:
     String sourceURL() const;
 #endif
 
+#if ENABLE(ENCRYPTED_MEDIA)
+    void keyAdded(const String& keySystem, const String& sessionId);
+    void keyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode);
+    void keyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength);
+    void keyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength);
+#endif
+
     String referrer() const;
     String userAgent() const;
 
index e1b3a55..486a049 100644 (file)
@@ -1,3 +1,25 @@
+2012-04-12  David Dorwin  <ddorwin@chromium.org>
+
+        Add Encrypted Media Extensions events and errors to HTMLMediaElement
+        https://bugs.webkit.org/show_bug.cgi?id=82974
+
+        Reviewed by Adam Barth.
+
+        The new events and errors are behind the ENABLE(ENCRYPTED_MEDIA) feature define.
+        Implementation is based on v0.1 of the draft proposal at
+        http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html#events.
+
+        * public/WebMediaPlayerClient.h:
+        * src/AssertMatchingEnums.cpp:
+        * src/WebMediaPlayerClientImpl.cpp:
+        (WebKit::WebMediaPlayerClientImpl::keyAdded):
+        (WebKit):
+        (WebKit::WebMediaPlayerClientImpl::keyError):
+        (WebKit::WebMediaPlayerClientImpl::keyMessage):
+        (WebKit::WebMediaPlayerClientImpl::keyNeeded):
+        * src/WebMediaPlayerClientImpl.h:
+        (WebMediaPlayerClientImpl):
+
 2012-04-12  Kent Tamura  <tkent@chromium.org>
 
         [Chromium] Enable INPUT_TYPE_DATE
index 19ea242..c9d31e4 100644 (file)
@@ -40,6 +40,15 @@ class WebURL;
 
 class WebMediaPlayerClient {
 public:
+    enum MediaKeyErrorCode {
+        UnknownError = 1,
+        ClientError,
+        ServiceError,
+        OutputError,
+        HardwareChangeError,
+        DomainError
+    };
+
     virtual void networkStateChanged() = 0;
     virtual void readyStateChanged() = 0;
     virtual void volumeChanged(float) = 0;
@@ -56,6 +65,10 @@ public:
     virtual WebMediaPlayer::Preload preload() const = 0;
     virtual void sourceOpened() = 0;
     virtual WebKit::WebURL sourceURL() const = 0;
+    virtual void keyAdded(const WebString&, const WebString&) = 0;
+    virtual void keyError(const WebString&, const WebString&, MediaKeyErrorCode, unsigned short systemCode) = 0;
+    virtual void keyMessage(const WebString&, const WebString&, const unsigned char*, unsigned) = 0;
+    virtual void keyNeeded(const WebString&, const WebString&, const unsigned char* initData, unsigned initDataLength) = 0;
     virtual void disableAcceleratedCompositing() = 0;
 protected:
     ~WebMediaPlayerClient() { }
index 293f489..72c2be6 100644 (file)
@@ -87,6 +87,7 @@
 #include "WebIconURL.h"
 #include "WebInputElement.h"
 #include "WebMediaPlayer.h"
+#include "WebMediaPlayerClient.h"
 #include "WebNotificationPresenter.h"
 #include "WebPageVisibilityState.h"
 #include "WebReferrerPolicy.h"
@@ -392,6 +393,13 @@ COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayer::LiveStream, MediaPlayer::LiveStream
 COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayer::NoError, MediaPlayer::NoError);
 COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayer::InvalidPlayerState, MediaPlayer::InvalidPlayerState);
 COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayer::KeySystemNotSupported, MediaPlayer::KeySystemNotSupported);
+
+COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayerClient::UnknownError, MediaPlayerClient::UnknownError);
+COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayerClient::ClientError, MediaPlayerClient::ClientError);
+COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayerClient::ServiceError, MediaPlayerClient::ServiceError);
+COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayerClient::OutputError, MediaPlayerClient::OutputError);
+COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayerClient::HardwareChangeError, MediaPlayerClient::HardwareChangeError);
+COMPILE_ASSERT_MATCHING_ENUM(WebMediaPlayerClient::DomainError, MediaPlayerClient::DomainError);
 #endif
 
 COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::FormatInvalid, VideoFrameChromium::Invalid);
index 321af6a..5c7b2c9 100644 (file)
@@ -217,6 +217,56 @@ WebKit::WebURL WebMediaPlayerClientImpl::sourceURL() const
 #endif
 }
 
+void WebMediaPlayerClientImpl::keyAdded(const WebString& keySystem, const WebString& sessionId)
+{
+#if ENABLE(ENCRYPTED_MEDIA)
+    ASSERT(m_mediaPlayer);
+    m_mediaPlayer->keyAdded(keySystem, sessionId);
+#else
+    UNUSED_PARAM(keySystem);
+    UNUSED_PARAM(sessionId);
+#endif
+}
+
+void WebMediaPlayerClientImpl::keyError(const WebString& keySystem, const WebString& sessionId, MediaKeyErrorCode errorCode, unsigned short systemCode)
+{
+#if ENABLE(ENCRYPTED_MEDIA)
+    ASSERT(m_mediaPlayer);
+    m_mediaPlayer->keyError(keySystem, sessionId, static_cast<MediaPlayerClient::MediaKeyErrorCode>(errorCode), systemCode);
+#else
+    UNUSED_PARAM(keySystem);
+    UNUSED_PARAM(sessionId);
+    UNUSED_PARAM(errorCode);
+    UNUSED_PARAM(systemCode);
+#endif
+}
+
+void WebMediaPlayerClientImpl::keyMessage(const WebString& keySystem, const WebString& sessionId, const unsigned char* message, unsigned messageLength)
+{
+#if ENABLE(ENCRYPTED_MEDIA)
+    ASSERT(m_mediaPlayer);
+    m_mediaPlayer->keyMessage(keySystem, sessionId, message, messageLength);
+#else
+    UNUSED_PARAM(keySystem);
+    UNUSED_PARAM(sessionId);
+    UNUSED_PARAM(message);
+    UNUSED_PARAM(messageLength);
+#endif
+}
+
+void WebMediaPlayerClientImpl::keyNeeded(const WebString& keySystem, const WebString& sessionId, const unsigned char* initData, unsigned initDataLength)
+{
+#if ENABLE(ENCRYPTED_MEDIA)
+    ASSERT(m_mediaPlayer);
+    m_mediaPlayer->keyNeeded(keySystem, sessionId, initData, initDataLength);
+#else
+    UNUSED_PARAM(keySystem);
+    UNUSED_PARAM(sessionId);
+    UNUSED_PARAM(initData);
+    UNUSED_PARAM(initDataLength);
+#endif
+}
+
 void WebMediaPlayerClientImpl::disableAcceleratedCompositing()
 {
     m_supportsAcceleratedCompositing = false;
index 88543a4..50bcc01 100644 (file)
@@ -86,6 +86,10 @@ public:
     virtual WebMediaPlayer::Preload preload() const;
     virtual void sourceOpened();
     virtual WebKit::WebURL sourceURL() const;
+    virtual void keyAdded(const WebString& keySystem, const WebString& sessionId);
+    virtual void keyError(const WebString& keySystem, const WebString& sessionId, MediaKeyErrorCode, unsigned short systemCode);
+    virtual void keyMessage(const WebString& keySystem, const WebString& sessionId, const unsigned char* message, unsigned messageLength);
+    virtual void keyNeeded(const WebString& keySystem, const WebString& sessionId, const unsigned char* initData, unsigned initDataLength);
     virtual void disableAcceleratedCompositing();
 
     // MediaPlayerPrivateInterface methods: