Diff
Modified: trunk/LayoutTests/ChangeLog (221960 => 221961)
--- trunk/LayoutTests/ChangeLog 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/ChangeLog 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,32 @@
+2017-09-13 Zan Dobersek <zdober...@igalia.com>
+
+ [EME] Implement CDMInstanceClearKey::updateLicense()
+ https://bugs.webkit.org/show_bug.cgi?id=176791
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ Update WPE baselines of the EME ClearKey tests.
+
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-events-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-keystatuses-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-keystatuses-multiple-sessions-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-sources-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-events-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multisession-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-src-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-update-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-immediately-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-onencrypted-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-two-videos-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-resetting-src-expected.txt:
+ * platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-update-disallowed-input-expected.txt:
+
2017-09-12 Carlos Alberto Lopez Perez <clo...@igalia.com>
[WPE] Rebaseline tests affected by r221909 (second part)
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-events-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-events-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-events-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, basic events assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, basic events
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-keystatuses-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-keystatuses-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-keystatuses-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, keystatuses assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, keystatuses
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-keystatuses-multiple-sessions-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-keystatuses-multiple-sessions-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-keystatuses-multiple-sessions-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, keystatuses, multiple sessions assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, keystatuses, multiple sessions
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, single key, encrypted then clear content assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, mp4, playback, single key, encrypted then clear content
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-sources-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-sources-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-sources-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, encrypted and clear sources assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, mp4, playback, encrypted and clear sources
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-events-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-events-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-events-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, check events assert_unreached: TypeError: Type error Reached unreachable code
+FAIL org.w3.clearkey, temporary, mp4, playback, check events assert_equals: Expected 1st event to be 'generaterequest' expected "generaterequest" but got "license-request"
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, single key assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, mp4, playback, single key
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, multikey audio/video assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, mp4, playback, multikey audio/video
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,5 @@
-FAIL org.w3.clearkey, successful playback, temporary, mp4, multiple keys, sequential assert_unreached: TypeError: Type error Reached unreachable code
+Harness Error (TIMEOUT), message = null
+TIMEOUT org.w3.clearkey, successful playback, temporary, mp4, multiple keys, sequential Test timed out
+
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,5 @@
-FAIL org.w3.clearkey, successful playback, temporary, mp4, multiple keys, sequential, readyState assert_unreached: TypeError: Type error Reached unreachable code
+Harness Error (TIMEOUT), message = null
+TIMEOUT org.w3.clearkey, successful playback, temporary, mp4, multiple keys, sequential, readyState Test timed out
+
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multisession-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multisession-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-multisession-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,5 @@
-FAIL org.w3.clearkey, temporary, mp4, playback with multiple sessions, multikey video assert_unreached: TypeError: Type error Reached unreachable code
+Harness Error (TIMEOUT), message = null
+TIMEOUT org.w3.clearkey, temporary, mp4, playback with multiple sessions, multikey video Test timed out
+
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-src-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-src-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-src-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,5 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, setMediaKeys after setting video.src assert_unreached: TypeError: Type error Reached unreachable code
+Harness Error (TIMEOUT), message = null
+TIMEOUT org.w3.clearkey, temporary, mp4, playback, setMediaKeys after setting video.src Test timed out
+
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-update-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-update-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-update-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, setMediaKeys after updating session assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, mp4, playback, setMediaKeys after updating session
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-immediately-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-immediately-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-immediately-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, setMediaKeys first assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, mp4, playback, setMediaKeys first
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-onencrypted-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-onencrypted-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-onencrypted-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback, setMediaKeys in encrypted event assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, mp4, playback, setMediaKeys in encrypted event
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-two-videos-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-two-videos-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-playback-temporary-two-videos-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, temporary, mp4, playback two videos assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, temporary, mp4, playback two videos
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, setmediakeys again after playback assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, setmediakeys again after playback
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-resetting-src-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-resetting-src-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-resetting-src-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-FAIL org.w3.clearkey, setmediakeys again after resetting src assert_unreached: TypeError: Type error Reached unreachable code
+PASS org.w3.clearkey, setmediakeys again after resetting src
Modified: trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-update-disallowed-input-expected.txt (221960 => 221961)
--- trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-update-disallowed-input-expected.txt 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/LayoutTests/platform/wpe/imported/w3c/web-platform-tests/encrypted-media/clearkey-mp4-update-disallowed-input-expected.txt 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,3 @@
-PASS update() with invalid response (longer than 64Kb characters) should fail.
+FAIL update() with invalid response (longer than 64Kb characters) should fail. assert_equals: expected "TypeError" but got "Error"
Modified: trunk/Source/WebCore/ChangeLog (221960 => 221961)
--- trunk/Source/WebCore/ChangeLog 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/Source/WebCore/ChangeLog 2017-09-13 07:37:13 UTC (rev 221961)
@@ -1,3 +1,43 @@
+2017-09-13 Zan Dobersek <zdober...@igalia.com>
+
+ [EME] Implement CDMInstanceClearKey::updateLicense()
+ https://bugs.webkit.org/show_bug.cgi?id=176791
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ Implement the updateLicense() method for CDMInstanceClearKey.
+ The response data is parsed as JSON, matching that agains either
+ 'license' or 'license release acknowledgement' formats (depending
+ on either 'keys' or 'kids' object keys being present). If any
+ format is recognized, appropriate steps are taken.
+
+ In case of the 'license' format, the passed-in keys are matched
+ against existing ones. If some keys have changed or have been
+ newly introduced, the key information is sorted by key ID size
+ and data to enforce order. After that the KeyStatusVector object
+ is constructed, containing key ID and status information for all
+ the keys associated with this session. Finally callback is
+ dispatched, signalling a successful operation and passing the
+ KeyStatusVector, if any, back to the caller.
+
+ In case of the 'license release acknowledgement' format, the
+ session data for this session ID is removed from the ClearKey state
+ singleton. The callback is dispatched signalling the session closure
+ and successfull completion of the operation.
+
+ Finally, if no format is deduced, the callback is again dispatched,
+ but now signalling an operation failure.
+
+ No new tests -- expectations for the relevant tests are updated
+ to reflect the introduced changes.
+
+ * platform/encryptedmedia/clearkey/CDMClearKey.cpp:
+ (WebCore::ClearKeyState::keys):
+ (WebCore::ClearKeyState::singleton):
+ (WebCore::parseLicenseFormat):
+ (WebCore::parseLicenseReleaseAcknowledgementFormat):
+ (WebCore::CDMInstanceClearKey::updateLicense):
+
2017-09-13 Ryosuke Niwa <rn...@webkit.org>
Refactor WebContentReader out of EditorMac and EditorIOS
Modified: trunk/Source/WebCore/platform/encryptedmedia/clearkey/CDMClearKey.cpp (221960 => 221961)
--- trunk/Source/WebCore/platform/encryptedmedia/clearkey/CDMClearKey.cpp 2017-09-13 07:17:43 UTC (rev 221960)
+++ trunk/Source/WebCore/platform/encryptedmedia/clearkey/CDMClearKey.cpp 2017-09-13 07:37:13 UTC (rev 221961)
@@ -37,11 +37,33 @@
#include "SharedBuffer.h"
#include <inspector/InspectorValues.h>
#include <wtf/MainThread.h>
+#include <wtf/text/Base64.h>
using namespace Inspector;
namespace WebCore {
+class ClearKeyState {
+ using KeyStore = HashMap<String, Vector<CDMInstanceClearKey::Key>>;
+
+public:
+ static ClearKeyState& singleton();
+
+ KeyStore& keys() { return m_keys; }
+
+private:
+ ClearKeyState();
+ KeyStore m_keys;
+};
+
+ClearKeyState& ClearKeyState::singleton()
+{
+ static ClearKeyState s_state;
+ return s_state;
+}
+
+ClearKeyState::ClearKeyState() = default;
+
RefPtr<InspectorObject> parseJSONObject(const SharedBuffer& buffer)
{
// Fail on large buffers whose size doesn't fit into a 32-bit unsigned integer.
@@ -59,6 +81,64 @@
return object;
}
+std::optional<Vector<CDMInstanceClearKey::Key>> parseLicenseFormat(const InspectorObject& root)
+{
+ // If the 'keys' key is present in the root object, parse the JSON further
+ // according to the specified 'license' format.
+ auto it = root.find("keys");
+ if (it == root.end())
+ return std::nullopt;
+
+ // Retrieve the keys array.
+ RefPtr<InspectorArray> keysArray;
+ if (!it->value->asArray(keysArray))
+ return std::nullopt;
+
+ Vector<CDMInstanceClearKey::Key> decodedKeys;
+ bool validFormat = std::all_of(keysArray->begin(), keysArray->end(),
+ [&decodedKeys] (const auto& value) {
+ RefPtr<InspectorObject> keyObject;
+ if (!value->asObject(keyObject))
+ return false;
+
+ String keyType;
+ if (!keyObject->getString("kty", keyType) || !equalLettersIgnoringASCIICase(keyType, "oct"))
+ return false;
+
+ String keyID, keyValue;
+ if (!keyObject->getString("kid", keyID) || !keyObject->getString("k", keyValue))
+ return false;
+
+ Vector<char> keyIDData, keyValueData;
+ if (!WTF::base64URLDecode(keyID, { keyIDData }) || !WTF::base64URLDecode(keyValue, { keyValueData }))
+ return false;
+
+ decodedKeys.append({ CDMInstanceClearKey::KeyStatus::Usable, SharedBuffer::create(WTFMove(keyIDData)), SharedBuffer::create(WTFMove(keyValueData)) });
+ return true;
+ });
+ if (!validFormat)
+ return std::nullopt;
+
+ return decodedKeys;
+}
+
+bool parseLicenseReleaseAcknowledgementFormat(const InspectorObject& root)
+{
+ // If the 'kids' key is present in the root object, parse the JSON further
+ // according to the specified 'license release acknowledgement' format.
+ auto it = root.find("kids");
+ if (it == root.end())
+ return false;
+
+ // Retrieve the kids array.
+ RefPtr<InspectorArray> kidsArray;
+ if (!it->value->asArray(kidsArray))
+ return false;
+
+ // FIXME: Return the key IDs and validate them.
+ return true;
+}
+
CDMFactoryClearKey& CDMFactoryClearKey::singleton()
{
static CDMFactoryClearKey s_factory;
@@ -252,15 +332,109 @@
});
}
-void CDMInstanceClearKey::updateLicense(const String&, LicenseType, const SharedBuffer&, LicenseUpdateCallback callback)
+void CDMInstanceClearKey::updateLicense(const String& sessionId, LicenseType, const SharedBuffer& response, LicenseUpdateCallback callback)
{
- callOnMainThread(
- [weakThis = m_weakPtrFactory.createWeakPtr(), callback = WTFMove(callback)] {
- if (!weakThis)
- return;
+ // Use a helper functor that schedules the callback dispatch, avoiding
+ // duplicated callOnMainThread() calls.
+ auto dispatchCallback =
+ [this, &callback](bool sessionWasClosed, std::optional<KeyStatusVector>&& changedKeys, SuccessValue succeeded) {
+ callOnMainThread(
+ [weakThis = m_weakPtrFactory.createWeakPtr(), callback = WTFMove(callback), sessionWasClosed, changedKeys = WTFMove(changedKeys), succeeded] () mutable {
+ if (!weakThis)
+ return;
- callback(false, std::nullopt, std::nullopt, std::nullopt, Failed);
- });
+ callback(sessionWasClosed, WTFMove(changedKeys), std::nullopt, std::nullopt, succeeded);
+ });
+ };
+
+ // Parse the response buffer as an JSON object.
+ RefPtr<InspectorObject> root = parseJSONObject(response);
+ if (!root) {
+ dispatchCallback(false, std::nullopt, SuccessValue::Failed);
+ return;
+ }
+
+ // Parse the response using 'license' formatting, if possible.
+ if (auto decodedKeys = parseLicenseFormat(*root)) {
+ // Retrieve the target Vector of Key objects for this session.
+ auto& keyVector = ClearKeyState::singleton().keys().ensure(sessionId, [] { return Vector<Key> { }; }).iterator->value;
+
+ // For each decoded key, find an existing item for the decoded key's ID. If none exist,
+ // the key is decoded. Otherwise, the key is updated in case there's a mismatch between
+ // the size or data of the existing and proposed key.
+ bool keysChanged = false;
+ for (auto& key : *decodedKeys) {
+ auto it = std::find_if(keyVector.begin(), keyVector.end(),
+ [&key] (const Key& containedKey) {
+ return containedKey.keyIDData->size() == key.keyIDData->size()
+ && !std::memcmp(containedKey.keyIDData->data(), key.keyIDData->data(), containedKey.keyIDData->size());
+ });
+ if (it != keyVector.end()) {
+ auto& existingKey = it->keyValueData;
+ auto& proposedKey = key.keyValueData;
+
+ // Update the existing Key if it differs from the proposed key in key value.
+ if (existingKey->size() != proposedKey->size() || std::memcmp(existingKey->data(), proposedKey->data(), existingKey->size())) {
+ *it = WTFMove(key);
+ keysChanged = true;
+ }
+ } else {
+ // In case a Key for this key ID doesn't exist yet, append the new one to keyVector.
+ keyVector.append(WTFMove(key));
+ keysChanged = true;
+ }
+ }
+
+ // In case of changed keys, we have to provide a KeyStatusVector of all the keys for
+ // this session.
+ std::optional<KeyStatusVector> changedKeys;
+ if (keysChanged) {
+ // First a helper Vector is constructed, cotaining pairs of SharedBuffer RefPtrs
+ // representint key ID data, and the corresponding key statuses.
+ // We can't use KeyStatusVector here because this Vector has to be sorted, which
+ // is not possible to do on Ref<> objects.
+ Vector<std::pair<RefPtr<SharedBuffer>, KeyStatus>> keys;
+ keys.reserveInitialCapacity(keyVector.size());
+ for (auto& it : keyVector)
+ keys.uncheckedAppend(std::pair<RefPtr<SharedBuffer>, KeyStatus> { it.keyIDData, it.status });
+
+ // Sort first by size, second by data.
+ std::sort(keys.begin(), keys.end(),
+ [] (const auto& a, const auto& b) {
+ if (a.first->size() != b.first->size())
+ return a.first->size() < b.first->size();
+
+ return std::memcmp(a.first->data(), b.first->data(), a.first->size()) < 0;
+ });
+
+ // Finally construct the mirroring KeyStatusVector object and move it into the
+ // std::optional<> object that will be passed to the callback.
+ KeyStatusVector keyStatusVector;
+ keyStatusVector.reserveInitialCapacity(keys.size());
+ for (auto& it : keys)
+ keyStatusVector.uncheckedAppend(std::pair<Ref<SharedBuffer>, KeyStatus> { *it.first, it.second });
+
+ changedKeys = WTFMove(keyStatusVector);
+ }
+
+ // Cache the key information Vector on CDMInstance for easier access from the pipeline.
+ m_keys = keyVector;
+
+ dispatchCallback(false, WTFMove(changedKeys), SuccessValue::Succeeded);
+ return;
+ }
+
+ // Parse the response using 'license release acknowledgement' formatting, if possible.
+ if (parseLicenseReleaseAcknowledgementFormat(*root)) {
+ // FIXME: Retrieve the key ID information and use it to validate the keys for this sessionId.
+ ClearKeyState::singleton().keys().remove(sessionId);
+ m_keys.clear();
+ dispatchCallback(true, std::nullopt, SuccessValue::Succeeded);
+ return;
+ }
+
+ // Bail in case no format was recognized.
+ dispatchCallback(false, std::nullopt, SuccessValue::Failed);
}
void CDMInstanceClearKey::loadSession(LicenseType, const String&, const String&, LoadSessionCallback callback)