Changeset 254334 in webkit
- Timestamp:
- Jan 10, 2020 4:32:31 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r254327 r254334 1 2020-01-10 Charlie Turner <mail@charles.plus> 2 3 [EME][ClearKey] Refactor CDMInstanceClearKey::updateLicense() 4 https://bugs.webkit.org/show_bug.cgi?id=205999 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 Covered by existing tests. 9 10 * platform/SharedBuffer.cpp: 11 (WebCore::SharedBuffer::toHexString const): Helper utility to view 12 a shared buffer's contents as a hex string. 13 * platform/SharedBuffer.h: 14 * platform/encryptedmedia/clearkey/CDMClearKey.cpp: 15 (WebCore::CDMInstanceClearKey::Key::keyIDAsString const): Uses the 16 new utility to return a hex string of the key ID for debugging. 17 (WebCore::CDMInstanceClearKey::Key::keyValueAsString const): 18 Ditto, but for the key data. 19 (WebCore::operator==): Added comparison operations to 20 CDMInstanceClearKey::Key to cleanup code in updateLicense. 21 (WebCore::operator<): 22 (WebCore::CDMInstanceSessionClearKey::updateLicense): Refactored 23 to use operators associated with the key class, so as to avoid 24 open-coded memcmp's in the middle of conditionals and other 25 techniques that made the code harder to read that necessary. 26 * platform/encryptedmedia/clearkey/CDMClearKey.h: 27 1 28 2020-01-10 Adrian Perez de Castro <aperez@igalia.com> 2 29 -
trunk/Source/WebCore/platform/SharedBuffer.cpp
r254087 r254334 30 30 31 31 #include <algorithm> 32 #include <wtf/HexNumber.h> 32 33 #include <wtf/persistence/PersistentCoders.h> 34 #include <wtf/text/StringBuilder.h> 33 35 #include <wtf/unicode/UTF8Conversion.h> 34 36 … … 131 133 element--; // std::upper_bound gives a pointer to the element that is greater than position. We want the element just before that. 132 134 return { element->segment.copyRef(), position - element->beginPosition }; 135 } 136 137 String SharedBuffer::toHexString() const 138 { 139 StringBuilder stringBuilder; 140 for (unsigned byteOffset = 0; byteOffset < size(); byteOffset++) { 141 const uint8_t byte = data()[byteOffset]; 142 stringBuilder.append(pad('0', 2, hex(byte))); 143 } 144 return stringBuilder.toString(); 133 145 } 134 146 -
trunk/Source/WebCore/platform/SharedBuffer.h
r254087 r254334 199 199 SharedBufferDataView getSomeData(size_t position) const; 200 200 201 String toHexString() const; 202 201 203 void hintMemoryNotNeededSoon() const; 202 204 -
trunk/Source/WebCore/platform/encryptedmedia/clearkey/CDMClearKey.cpp
r249548 r254334 35 35 #include "CDMRestrictions.h" 36 36 #include "CDMSessionType.h" 37 #include "Logging.h" 37 38 #include "SharedBuffer.h" 38 39 #include <wtf/JSONValues.h> … … 538 539 } 539 540 541 String CDMInstanceClearKey::Key::keyIDAsString() const 542 { 543 return makeString("[", keyIDData->toHexString(), "]"); 544 } 545 546 String CDMInstanceClearKey::Key::keyValueAsString() const 547 { 548 return makeString("[", keyValueData->toHexString(), "]"); 549 } 550 551 bool operator==(const CDMInstanceClearKey::Key& k1, const CDMInstanceClearKey::Key& k2) 552 { 553 ASSERT(k1.keyIDData); 554 ASSERT(k2.keyIDData); 555 556 return *k1.keyIDData == *k2.keyIDData; 557 } 558 559 bool operator<(const CDMInstanceClearKey::Key& k1, const CDMInstanceClearKey::Key& k2) 560 { 561 ASSERT(k1.keyIDData); 562 ASSERT(k2.keyIDData); 563 564 if (k1.keyIDData->size() != k2.keyIDData->size()) 565 return k1.keyIDData->size() < k2.keyIDData->size(); 566 567 return memcmp(k1.keyIDData->data(), k2.keyIDData->data(), k1.keyIDData->size()); 568 } 569 540 570 void CDMInstanceSessionClearKey::requestLicense(LicenseType, const AtomString& initDataType, Ref<SharedBuffer>&& initData, LicenseCallback&& callback) 541 571 { … … 573 603 }; 574 604 575 // Parse the response buffer as an JSON object.576 605 RefPtr<JSON::Object> root = parseJSONObject(response); 577 606 if (!root) { … … 580 609 } 581 610 582 // Parse the response using 'license' formatting, if possible. 611 LOG(EME, "EME - ClearKey - updating license for session %s", sessionId.utf8().data()); 612 583 613 if (auto decodedKeys = parseLicenseFormat(*root)) { 584 614 // Retrieve the target Vector of Key objects for this session. 585 auto& keyVector = ClearKeyState::singleton().keys().ensure(sessionId, [] { return Vector<CDMInstanceClearKey::Key> { }; }).iterator->value; 586 587 // For each decoded key, find an existing item for the decoded key's ID. If none exist, 588 // the key is decoded. Otherwise, the key is updated in case there's a mismatch between 589 // the size or data of the existing and proposed key. 615 // FIXME: Refactor this state management code. 616 Vector<CDMInstanceClearKey::Key>& keyVector = ClearKeyState::singleton().keys().ensure(sessionId, [] { return Vector<CDMInstanceClearKey::Key> { }; }).iterator->value; 617 590 618 bool keysChanged = false; 591 for (auto& key : *decodedKeys) {592 auto it = std::find_if(keyVector.begin(), keyVector.end(),593 [&key] (const CDMInstanceClearKey::Key& containedKey) {594 return containedKey.keyIDData->size() == key.keyIDData->size()595 && !std::memcmp(containedKey.keyIDData->data(), key.keyIDData->data(), containedKey.keyIDData->size());619 for (auto& decodedKey : *decodedKeys) { 620 LOG(EME, "EME - ClearKey - Decoded a key with ID %s and key data %s", decodedKey.keyIDAsString().utf8().data(), decodedKey.keyValueAsString().utf8().data()); 621 auto keyWithMatchingKeyID = std::find_if(keyVector.begin(), keyVector.end(), 622 [&decodedKey] (const CDMInstanceClearKey::Key& containedKey) { 623 return containedKey == decodedKey; 596 624 }); 597 if (it != keyVector.end()) { 598 auto& existingKey = it->keyValueData; 599 auto& proposedKey = key.keyValueData; 600 601 // Update the existing Key if it differs from the proposed key in key value. 602 if (existingKey->size() != proposedKey->size() || std::memcmp(existingKey->data(), proposedKey->data(), existingKey->size())) { 603 *it = WTFMove(key); 625 if (keyWithMatchingKeyID != keyVector.end()) { 626 LOG(EME, "EME - ClearKey - Existing key found with data %s", keyWithMatchingKeyID->keyValueAsString().utf8().data()); 627 628 if (!keyWithMatchingKeyID->hasSameKeyValue(decodedKey)) { 629 LOG(EME, "EME - ClearKey - Updating key since the data are different"); 630 *keyWithMatchingKeyID = WTFMove(decodedKey); 604 631 keysChanged = true; 605 632 } 606 633 } else { 607 // In case a Key for this key ID doesn't exist yet, append the new one to keyVector.608 keyVector.append(WTFMove( key));634 LOG(EME, "EME - ClearKey - This is a new key"); 635 keyVector.append(WTFMove(decodedKey)); 609 636 keysChanged = true; 610 637 } 611 638 } 612 639 613 // In case of changed keys, we have to provide a KeyStatusVector of all the keys for614 // this session. 640 LOG(EME, "EME - ClearKey - Update has provided %zu keys", keyVector.size()); 641 615 642 Optional<KeyStatusVector> changedKeys; 616 643 if (keysChanged) { 617 // First a helper Vector is constructed, cotaining pairs of SharedBuffer RefPtrs 618 // representint key ID data, and the corresponding key statuses. 619 // We can't use KeyStatusVector here because this Vector has to be sorted, which 620 // is not possible to do on Ref<> objects. 621 Vector<std::pair<RefPtr<SharedBuffer>, KeyStatus>> keys; 622 keys.reserveInitialCapacity(keyVector.size()); 623 for (auto& it : keyVector) 624 keys.uncheckedAppend(std::pair<RefPtr<SharedBuffer>, KeyStatus> { it.keyIDData, it.status }); 625 626 // Sort first by size, second by data. 627 std::sort(keys.begin(), keys.end(), 628 [] (const auto& a, const auto& b) { 629 if (a.first->size() != b.first->size()) 630 return a.first->size() < b.first->size(); 631 632 return std::memcmp(a.first->data(), b.first->data(), a.first->size()) < 0; 633 }); 634 635 // Finally construct the mirroring KeyStatusVector object and move it into the 636 // Optional<> object that will be passed to the callback. 644 // Sort by key IDs. 645 std::sort(keyVector.begin(), keyVector.end()); 646 637 647 KeyStatusVector keyStatusVector; 638 keyStatusVector.reserveInitialCapacity(key s.size());639 for (auto& it : keys)640 keyStatusVector.uncheckedAppend(std::pair<Ref<SharedBuffer>, KeyStatus> { * it.first, it.second});648 keyStatusVector.reserveInitialCapacity(keyVector.size()); 649 for (auto& key : keyVector) 650 keyStatusVector.uncheckedAppend(std::pair<Ref<SharedBuffer>, KeyStatus> { *key.keyIDData, key.status }); 641 651 642 652 changedKeys = WTFMove(keyStatusVector); … … 647 657 } 648 658 649 // Parse the response using 'license release acknowledgement' formatting, if possible.650 659 if (parseLicenseReleaseAcknowledgementFormat(*root)) { 651 660 // FIXME: Retrieve the key ID information and use it to validate the keys for this sessionId. -
trunk/Source/WebCore/platform/encryptedmedia/clearkey/CDMClearKey.h
r249548 r254334 111 111 RefPtr<SharedBuffer> keyIDData; 112 112 RefPtr<SharedBuffer> keyValueData; 113 114 String keyIDAsString() const; 115 String keyValueAsString() const; 116 117 bool hasSameKeyValue(const Key &other) 118 { 119 ASSERT(keyValueData); 120 ASSERT(other.keyValueData); 121 return *keyValueData == *other.keyValueData; 122 } 123 124 // Two keys are equal if they have the same ID, ignoring key value and status. 125 friend bool operator==(const Key &k1, const Key &k2); 126 // Key's are ordered by their IDs, first by size, then by contents. 127 friend bool operator<(const Key &k1, const Key &k2); 128 129 friend bool operator!=(const Key &k1, const Key &k2) { return !(operator==(k1, k2)); } 130 friend bool operator>(const Key &k1, const Key &k2) { return !operator==(k1, k2) && !operator<(k1, k2); } 131 friend bool operator<=(const Key &k1, const Key &k2) { return !operator>(k1, k2); } 132 friend bool operator>=(const Key &k1, const Key &k2) { return !operator<(k1, k2); } 113 133 }; 114 134 -
trunk/Tools/ChangeLog
r254331 r254334 1 2020-01-10 Charlie Turner <mail@charles.plus> 2 3 [EME][ClearKey] Refactor CDMClearKey::update() 4 https://bugs.webkit.org/show_bug.cgi?id=205999 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 * TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp: 9 (TestWebKitAPI::TEST_F): Added a test for the new toHexString 10 helper. It should make sure to zero pad each byte to two 11 characters, so that it's easy to read. 12 1 13 2020-01-10 Carlos Garcia Campos <cgarcia@igalia.com> 2 14 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp
r251089 r254334 218 218 } 219 219 220 } 220 TEST_F(SharedBufferTest, toHexString) 221 { 222 Vector<char> t1 = {0x11, 0x5, 0x12}; 223 auto buffer = SharedBuffer::create(); 224 buffer->append(WTFMove(t1)); 225 String result = buffer->toHexString(); 226 EXPECT_EQ(result, "110512"); 227 buffer->clear(); 228 EXPECT_EQ(buffer->toHexString(), ""); 229 } 230 231 }
Note: See TracChangeset
for help on using the changeset viewer.