diff --git a/packager/media/base/fixed_key_source.cc b/packager/media/base/fixed_key_source.cc index 64918372f2..bae4c5de22 100644 --- a/packager/media/base/fixed_key_source.cc +++ b/packager/media/base/fixed_key_source.cc @@ -15,18 +15,8 @@ namespace media { FixedKeySource::~FixedKeySource() {} -Status FixedKeySource::FetchKeys(const std::vector& pssh_box) { - // Do nothing for fixed key encryption/decryption. - return Status::OK; -} - -Status FixedKeySource::FetchKeys( - const std::vector>& key_ids) { - // Do nothing for fixed key encryption/decryption. - return Status::OK; -} - -Status FixedKeySource::FetchKeys(uint32_t asset_id) { +Status FixedKeySource::FetchKeys(EmeInitDataType init_data_type, + const std::vector& init_data) { // Do nothing for fixed key encryption/decryption. return Status::OK; } diff --git a/packager/media/base/fixed_key_source.h b/packager/media/base/fixed_key_source.h index e0f2674ca4..df07d946de 100644 --- a/packager/media/base/fixed_key_source.h +++ b/packager/media/base/fixed_key_source.h @@ -30,10 +30,8 @@ class FixedKeySource : public KeySource { /// @name KeySource implementation overrides. /// @{ - Status FetchKeys(const std::vector& pssh_box) override; - Status FetchKeys(const std::vector>& key_ids) override; - Status FetchKeys(uint32_t asset_id) override; - + Status FetchKeys(EmeInitDataType init_data_type, + const std::vector& init_data) override; Status GetKey(TrackType track_type, EncryptionKey* key) override; Status GetKey(const std::vector& key_id, EncryptionKey* key) override; diff --git a/packager/media/base/key_source.h b/packager/media/base/key_source.h index 4498ebfdb3..2883e6cb82 100644 --- a/packager/media/base/key_source.h +++ b/packager/media/base/key_source.h @@ -16,6 +16,21 @@ namespace shaka { namespace media { +/// Encrypted media init data types. It is extended from: +/// https://www.w3.org/TR/eme-initdata-registry/#registry. +enum class EmeInitDataType { + UNKNOWN, + /// One or multiple PSSH boxes. + CENC, + /// WebM init data is basically KeyId. + WEBM, + /// JSON formatted key ids. + KEYIDS, + /// Widevine classic asset id. + WIDEVINE_CLASSIC, + MAX = WIDEVINE_CLASSIC +}; + struct EncryptionKey { EncryptionKey(); ~EncryptionKey(); @@ -43,22 +58,12 @@ class KeySource { KeySource(); virtual ~KeySource(); - /// Fetch keys for CENC from the key server. - /// @param pssh_box The entire PSSH box for the content to be decrypted + /// Fetch keys based on the specified encrypted media init data. + /// @param init_data_type specifies the encrypted media init data type. + /// @param init_data contains the init data. /// @return OK on success, an error status otherwise. - virtual Status FetchKeys(const std::vector& pssh_box) = 0; - - /// Fetch keys for CENC from the key server. - /// @param key_ids the key IDs for the keys to fetch from the server. - /// @return OK on success, an error status otherwise. - virtual Status FetchKeys( - const std::vector>& key_ids) = 0; - - /// Fetch keys for WVM decryption from the key server. - /// @param asset_id is the Widevine Classic asset ID for the content to be - /// decrypted. - /// @return OK on success, an error status otherwise. - virtual Status FetchKeys(uint32_t asset_id) = 0; + virtual Status FetchKeys(EmeInitDataType init_data_type, + const std::vector& init_data) = 0; /// Get encryption key of the specified track type. /// @param track_type is the type of track for which retrieving the key. diff --git a/packager/media/base/playready_key_source.cc b/packager/media/base/playready_key_source.cc index 8ef375d19a..ed6a6d52cd 100644 --- a/packager/media/base/playready_key_source.cc +++ b/packager/media/base/playready_key_source.cc @@ -310,19 +310,9 @@ Status PlayReadyKeySource::FetchKeysWithProgramIdentifier( return Status::OK; } -Status PlayReadyKeySource::FetchKeys(const std::vector& pssh_box) { - // Does nothing for playready encryption/decryption. - return Status::OK; -} - -Status PlayReadyKeySource::FetchKeys( - const std::vector>& key_ids) { - // Does nothing for playready encryption/decryption. - return Status::OK; -} - -Status PlayReadyKeySource::FetchKeys(uint32_t asset_id) { - // Does nothing for playready encryption/decryption. +Status PlayReadyKeySource::FetchKeys(EmeInitDataType init_data_type, + const std::vector& init_data) { + // Do nothing for playready encryption/decryption. return Status::OK; } diff --git a/packager/media/base/playready_key_source.h b/packager/media/base/playready_key_source.h index 00ebf4ba00..290e18281e 100644 --- a/packager/media/base/playready_key_source.h +++ b/packager/media/base/playready_key_source.h @@ -40,10 +40,8 @@ class PlayReadyKeySource : public KeySource { /// @name KeySource implementation overrides. /// @{ - Status FetchKeys(const std::vector& pssh_box) override; - Status FetchKeys(const std::vector>& key_ids) override; - Status FetchKeys(uint32_t asset_id) override; - + Status FetchKeys(EmeInitDataType init_data_type, + const std::vector& init_data) override; Status GetKey(TrackType track_type, EncryptionKey* key) override; Status GetKey(const std::vector& key_id, EncryptionKey* key) override; diff --git a/packager/media/base/widevine_key_source.cc b/packager/media/base/widevine_key_source.cc index f1ceee1c2d..0d8f40c037 100644 --- a/packager/media/base/widevine_key_source.cc +++ b/packager/media/base/widevine_key_source.cc @@ -14,6 +14,7 @@ #include "packager/base/json/json_writer.h" #include "packager/media/base/fixed_key_source.h" #include "packager/media/base/http_key_fetcher.h" +#include "packager/media/base/network_util.h" #include "packager/media/base/producer_consumer_queue.h" #include "packager/media/base/protection_system_specific_info.h" #include "packager/media/base/rcheck.h" @@ -41,6 +42,18 @@ const int kDefaultCryptoPeriodCount = 10; const int kGetKeyTimeoutInSeconds = 5 * 60; // 5 minutes. const int kKeyFetchTimeoutInSeconds = 60; // 1 minute. +std::vector StringToBytes(const std::string& string) { + return std::vector(string.begin(), string.end()); +} + +std::vector WidevinePsshFromKeyId( + const std::vector>& key_ids) { + media::WidevinePsshData widevine_pssh_data; + for (const std::vector& key_id : key_ids) + widevine_pssh_data.add_key_id(key_id.data(), key_id.size()); + return StringToBytes(widevine_pssh_data.SerializeAsString()); +} + bool Base64StringToBytes(const std::string& base64_string, std::vector* bytes) { DCHECK(bytes); @@ -147,61 +160,63 @@ Status WidevineKeySource::FetchKeys(const std::vector& content_id, return FetchKeysInternal(!kEnableKeyRotation, 0, false); } -Status WidevineKeySource::FetchKeys(const std::vector& pssh_box) { - const std::vector widevine_system_id( - kWidevineSystemId, kWidevineSystemId + arraysize(kWidevineSystemId)); - - ProtectionSystemSpecificInfo info; - if (!info.Parse(pssh_box.data(), pssh_box.size())) - return Status(error::PARSER_FAILURE, "Error parsing the PSSH box."); - - if (info.system_id() == widevine_system_id) { - base::AutoLock scoped_lock(lock_); - request_dict_.Clear(); - std::string pssh_data_base64_string; - - BytesToBase64String(info.pssh_data(), &pssh_data_base64_string); - request_dict_.SetString("pssh_data", pssh_data_base64_string); - return FetchKeysInternal(!kEnableKeyRotation, 0, false); - } else if (!info.key_ids().empty()) { - // This is not a Widevine PSSH box. Try making the request for the key-IDs. - // Even if this is a different key-system, it should still work. Either - // the server will not recognize it and return an error, or it will - // recognize it and the key must be correct (or the content is bad). - return FetchKeys(info.key_ids()); +Status WidevineKeySource::FetchKeys(EmeInitDataType init_data_type, + const std::vector& init_data) { + std::vector pssh_data; + uint32_t asset_id = 0; + switch (init_data_type) { + case EmeInitDataType::CENC: { + const std::vector widevine_system_id( + kWidevineSystemId, kWidevineSystemId + arraysize(kWidevineSystemId)); + std::vector protection_systems_info; + if (!ProtectionSystemSpecificInfo::ParseBoxes( + init_data.data(), init_data.size(), &protection_systems_info)) { + return Status(error::PARSER_FAILURE, "Error parsing the PSSH boxes."); + } + for (const auto& info: protection_systems_info) { + // Use Widevine PSSH if available otherwise construct a Widevine PSSH + // from the first available key ids. + if (info.system_id() == widevine_system_id) { + pssh_data = info.pssh_data(); + break; + } else if (pssh_data.empty() && !info.key_ids().empty()) { + pssh_data = WidevinePsshFromKeyId(info.key_ids()); + // Continue to see if there is any Widevine PSSH. The KeyId generated + // PSSH is only used if a Widevine PSSH could not be found. + continue; + } + } + if (pssh_data.empty()) + return Status(error::INVALID_ARGUMENT, "No supported PSSHs found."); + break; + } + case EmeInitDataType::WEBM: + pssh_data = WidevinePsshFromKeyId({init_data}); + break; + case EmeInitDataType::WIDEVINE_CLASSIC: + if (init_data.size() < sizeof(asset_id)) + return Status(error::INVALID_ARGUMENT, "Invalid asset id."); + asset_id = ntohlFromBuffer(init_data.data()); + break; + default: + LOG(ERROR) << "Init data type " << static_cast(init_data_type) + << " not supported."; + return Status(error::INVALID_ARGUMENT, "Unsupported init data type."); + } + const bool widevine_classic = + init_data_type == EmeInitDataType::WIDEVINE_CLASSIC; + base::AutoLock scoped_lock(lock_); + request_dict_.Clear(); + if (widevine_classic) { + // Javascript/JSON does not support int64_t or unsigned numbers. Use double + // instead as 32-bit integer can be lossless represented using double. + request_dict_.SetDouble("asset_id", asset_id); } else { - return Status(error::NOT_FOUND, "No key IDs given in PSSH box."); + std::string pssh_data_base64_string; + BytesToBase64String(pssh_data, &pssh_data_base64_string); + request_dict_.SetString("pssh_data", pssh_data_base64_string); } -} - -Status WidevineKeySource::FetchKeys( - const std::vector>& key_ids) { - base::AutoLock scoped_lock(lock_); - request_dict_.Clear(); - std::string pssh_data_base64_string; - - // Generate Widevine PSSH data from the key-IDs. - WidevinePsshData widevine_pssh_data; - for (size_t i = 0; i < key_ids.size(); i++) { - widevine_pssh_data.add_key_id(key_ids[i].data(), key_ids[i].size()); - } - - const std::string serialized_string = widevine_pssh_data.SerializeAsString(); - std::vector pssh_data(serialized_string.begin(), - serialized_string.end()); - - BytesToBase64String(pssh_data, &pssh_data_base64_string); - request_dict_.SetString("pssh_data", pssh_data_base64_string); - return FetchKeysInternal(!kEnableKeyRotation, 0, false); -} - -Status WidevineKeySource::FetchKeys(uint32_t asset_id) { - base::AutoLock scoped_lock(lock_); - request_dict_.Clear(); - // Javascript/JSON does not support int64_t or unsigned numbers. Use double - // instead as 32-bit integer can be lossless represented using double. - request_dict_.SetDouble("asset_id", asset_id); - return FetchKeysInternal(!kEnableKeyRotation, 0, true); + return FetchKeysInternal(!kEnableKeyRotation, 0, widevine_classic); } Status WidevineKeySource::GetKey(TrackType track_type, EncryptionKey* key) { @@ -566,7 +581,9 @@ bool WidevineKeySource::ExtractEncryptionKey( DCHECK(!encryption_key_map.empty()); if (!enable_key_rotation) { - encryption_key_map_.swap(encryption_key_map); + // Merge with previously requested keys. + for (auto& pair : encryption_key_map) + encryption_key_map_[pair.first] = std::move(pair.second); return true; } return PushToKeyPool(&encryption_key_map); diff --git a/packager/media/base/widevine_key_source.h b/packager/media/base/widevine_key_source.h index 3e3717ef69..92c3022565 100644 --- a/packager/media/base/widevine_key_source.h +++ b/packager/media/base/widevine_key_source.h @@ -36,10 +36,8 @@ class WidevineKeySource : public KeySource { /// @name KeySource implementation overrides. /// @{ - Status FetchKeys(const std::vector& pssh_box) override; - Status FetchKeys(const std::vector>& key_ids) override; - Status FetchKeys(uint32_t asset_id) override; - + Status FetchKeys(EmeInitDataType init_data_type, + const std::vector& init_data) override; Status GetKey(TrackType track_type, EncryptionKey* key) override; Status GetKey(const std::vector& key_id, EncryptionKey* key) override; diff --git a/packager/media/base/widevine_key_source_unittest.cc b/packager/media/base/widevine_key_source_unittest.cc index b81175a386..6b19fe4077 100644 --- a/packager/media/base/widevine_key_source_unittest.cc +++ b/packager/media/base/widevine_key_source_unittest.cc @@ -75,6 +75,7 @@ const uint8_t kRequestKeyId[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; // 32-bit with leading bit set, to verify that big uint32_t can be handled // correctly. const uint32_t kClassicAssetId = 0x80038cd9; +const uint8_t kClassicAssetIdBytes[] = {0x80, 0x03, 0x8c, 0xd9}; std::string Base64Encode(const std::string& input) { std::string output; @@ -319,11 +320,11 @@ TEST_P(WidevineKeySourceTest, LicenseStatusCencWithPsshBoxOK) { widevine_key_source_->set_signer(std::move(mock_request_signer_)); std::vector pssh_box(kRequestPsshBox, kRequestPsshBox + arraysize(kRequestPsshBox)); - ASSERT_OK(widevine_key_source_->FetchKeys(pssh_box)); + ASSERT_OK(widevine_key_source_->FetchKeys(EmeInitDataType::CENC, pssh_box)); VerifyKeys(false); } -TEST_P(WidevineKeySourceTest, LicenseStatusCencWithKeyIdsOK) { +TEST_P(WidevineKeySourceTest, LicenseStatusCencWithKeyIdOK) { std::string expected_pssh_data( kRequestPsshDataFromKeyIds, kRequestPsshDataFromKeyIds + arraysize(kRequestPsshDataFromKeyIds)); @@ -341,10 +342,9 @@ TEST_P(WidevineKeySourceTest, LicenseStatusCencWithKeyIdsOK) { CreateWidevineKeySource(); widevine_key_source_->set_signer(std::move(mock_request_signer_)); - std::vector> key_ids; - key_ids.push_back(std::vector( - kRequestKeyId, kRequestKeyId + arraysize(kRequestKeyId))); - ASSERT_OK(widevine_key_source_->FetchKeys(key_ids)); + std::vector key_id(kRequestKeyId, + kRequestKeyId + arraysize(kRequestKeyId)); + ASSERT_OK(widevine_key_source_->FetchKeys(EmeInitDataType::WEBM, key_id)); VerifyKeys(false); } @@ -363,7 +363,10 @@ TEST_P(WidevineKeySourceTest, LicenseStatusClassicOK) { CreateWidevineKeySource(); widevine_key_source_->set_signer(std::move(mock_request_signer_)); - ASSERT_OK(widevine_key_source_->FetchKeys(kClassicAssetId)); + ASSERT_OK(widevine_key_source_->FetchKeys( + EmeInitDataType::WIDEVINE_CLASSIC, + std::vector(std::begin(kClassicAssetIdBytes), + std::end(kClassicAssetIdBytes)))); VerifyKeys(true); } diff --git a/packager/media/formats/mp4/mp4_media_parser.cc b/packager/media/formats/mp4/mp4_media_parser.cc index e8513a80b1..1b6e93ad3c 100644 --- a/packager/media/formats/mp4/mp4_media_parser.cc +++ b/packager/media/formats/mp4/mp4_media_parser.cc @@ -640,27 +640,18 @@ bool MP4MediaParser::FetchKeysIfNecessary( if (!decryption_key_source_) return true; - Status status; - for (std::vector::const_iterator iter = - headers.begin(); iter != headers.end(); ++iter) { - status = decryption_key_source_->FetchKeys(iter->raw_box); - if (!status.ok()) { - // If there is an error, try using the next PSSH box and report if none - // work. - VLOG(1) << "Unable to fetch decryption keys: " << status - << ", trying the next PSSH box"; - continue; - } - return true; + std::vector pssh_raw_data; + for (const auto& header : headers) { + pssh_raw_data.insert(pssh_raw_data.end(), header.raw_box.begin(), + header.raw_box.end()); } - + Status status = + decryption_key_source_->FetchKeys(EmeInitDataType::CENC, pssh_raw_data); if (!status.ok()) { LOG(ERROR) << "Error fetching decryption keys: " << status; return false; } - - LOG(ERROR) << "No viable 'pssh' box found for content decryption."; - return false; + return true; } bool MP4MediaParser::EnqueueSample(bool* err) { diff --git a/packager/media/formats/mp4/mp4_media_parser_unittest.cc b/packager/media/formats/mp4/mp4_media_parser_unittest.cc index 7731889d26..fdb2e72a69 100644 --- a/packager/media/formats/mp4/mp4_media_parser_unittest.cc +++ b/packager/media/formats/mp4/mp4_media_parser_unittest.cc @@ -31,7 +31,9 @@ const char kKeyId[] = "0123456789012345"; class MockKeySource : public FixedKeySource { public: - MOCK_METHOD1(FetchKeys, Status(const std::vector& pssh_data)); + MOCK_METHOD2(FetchKeys, + Status(EmeInitDataType init_data_type, + const std::vector& init_data)); MOCK_METHOD2(GetKey, Status(const std::vector& key_id, EncryptionKey* key)); }; @@ -247,7 +249,7 @@ TEST_F(MP4MediaParserTest, CencInitWithoutDecryptionSource) { TEST_F(MP4MediaParserTest, CencWithDecryptionSourceAndAuxInMdat) { MockKeySource mock_key_source; - EXPECT_CALL(mock_key_source, FetchKeys(_)).WillOnce(Return(Status::OK)); + EXPECT_CALL(mock_key_source, FetchKeys(_, _)).WillOnce(Return(Status::OK)); EncryptionKey encryption_key; encryption_key.key.assign(kKey, kKey + strlen(kKey)); @@ -266,7 +268,7 @@ TEST_F(MP4MediaParserTest, CencWithDecryptionSourceAndAuxInMdat) { TEST_F(MP4MediaParserTest, CencWithDecryptionSourceAndSenc) { MockKeySource mock_key_source; - EXPECT_CALL(mock_key_source, FetchKeys(_)).WillOnce(Return(Status::OK)); + EXPECT_CALL(mock_key_source, FetchKeys(_, _)).WillOnce(Return(Status::OK)); EncryptionKey encryption_key; encryption_key.key.assign(kKey, kKey + strlen(kKey)); diff --git a/packager/media/formats/webm/webm_media_parser.cc b/packager/media/formats/webm/webm_media_parser.cc index 7d08f8e4fd..be231eb797 100644 --- a/packager/media/formats/webm/webm_media_parser.cc +++ b/packager/media/formats/webm/webm_media_parser.cc @@ -242,17 +242,19 @@ bool WebMMediaParser::FetchKeysIfNecessary( if (!decryption_key_source_) return true; - std::vector> key_ids; + Status status; if (!audio_encryption_key_id.empty()) { - key_ids.push_back(std::vector(audio_encryption_key_id.begin(), - audio_encryption_key_id.end())); + status.Update(decryption_key_source_->FetchKeys( + EmeInitDataType::WEBM, + std::vector(audio_encryption_key_id.begin(), + audio_encryption_key_id.end()))); } if (!video_encryption_key_id.empty()) { - key_ids.push_back(std::vector(video_encryption_key_id.begin(), - video_encryption_key_id.end())); + status.Update(decryption_key_source_->FetchKeys( + EmeInitDataType::WEBM, + std::vector(video_encryption_key_id.begin(), + video_encryption_key_id.end()))); } - - Status status = decryption_key_source_->FetchKeys(key_ids); if (!status.ok()) { LOG(ERROR) << "Error fetching decryption keys: " << status; return false; diff --git a/packager/media/formats/wvm/wvm_media_parser.cc b/packager/media/formats/wvm/wvm_media_parser.cc index 09dfc33af6..83376816aa 100644 --- a/packager/media/formats/wvm/wvm_media_parser.cc +++ b/packager/media/formats/wvm/wvm_media_parser.cc @@ -1058,21 +1058,23 @@ bool WvmMediaParser::EmitSample(uint32_t parsed_audio_or_video_stream_id, return true; } -bool WvmMediaParser::GetAssetKey(const uint32_t asset_id, +bool WvmMediaParser::GetAssetKey(const uint8_t* asset_id, EncryptionKey* encryption_key) { DCHECK(decryption_key_source_); - Status status = decryption_key_source_->FetchKeys(asset_id); + Status status = decryption_key_source_->FetchKeys( + EmeInitDataType::WIDEVINE_CLASSIC, + std::vector(asset_id, asset_id + sizeof(uint32_t))); if (!status.ok()) { - LOG(ERROR) << "Fetch Key(s) failed for AssetID = " << asset_id - << ", error = " << status; + LOG(ERROR) << "Fetch Key(s) failed for AssetID = " + << ntohlFromBuffer(asset_id) << ", error = " << status; return false; } status = decryption_key_source_->GetKey(KeySource::TRACK_TYPE_HD, encryption_key); if (!status.ok()) { - LOG(ERROR) << "Fetch Key(s) failed for AssetID = " << asset_id - << ", error = " << status; + LOG(ERROR) << "Fetch Key(s) failed for AssetID = " + << ntohlFromBuffer(asset_id) << ", error = " << status; return false; } @@ -1097,22 +1099,17 @@ bool WvmMediaParser::ProcessEcm() { ecm_data += sizeof(uint32_t); // old version field - skip. ecm_data += sizeof(uint32_t); // clear lead - skip. ecm_data += sizeof(uint32_t); // system id(includes ECM version) - skip. - uint32_t asset_id = ntohlFromBuffer(ecm_data); - if (asset_id == 0) { - LOG(ERROR) << "AssetID in ECM is not valid."; - return false; - } - ecm_data += sizeof(uint32_t); // asset_id. EncryptionKey encryption_key; - if (!GetAssetKey(asset_id, &encryption_key)) { + if (!GetAssetKey(ecm_data, &encryption_key)) { return false; } if (encryption_key.key.size() < kAssetKeySizeBytes) { LOG(ERROR) << "Asset Key size of " << encryption_key.key.size() - << " for AssetID = " << asset_id + << " for AssetID = " << ntohlFromBuffer(ecm_data) << " is less than minimum asset key size."; return false; } + ecm_data += sizeof(uint32_t); // asset_id. // Legacy WVM content may have asset keys > 16 bytes. // Use only the first 16 bytes of the asset key to get // the content key. diff --git a/packager/media/formats/wvm/wvm_media_parser.h b/packager/media/formats/wvm/wvm_media_parser.h index 9884249d7e..87200cb929 100644 --- a/packager/media/formats/wvm/wvm_media_parser.h +++ b/packager/media/formats/wvm/wvm_media_parser.h @@ -200,7 +200,7 @@ class WvmMediaParser : public MediaParser { // to ouput media sample as encrypted. bool Output(bool must_process_encrypted); - bool GetAssetKey(const uint32_t asset_id, EncryptionKey* encryption_key); + bool GetAssetKey(const uint8_t* asset_id, EncryptionKey* encryption_key); // Callback invoked by the ES media parser // to emit a new audio/video access unit. diff --git a/packager/media/formats/wvm/wvm_media_parser_unittest.cc b/packager/media/formats/wvm/wvm_media_parser_unittest.cc index e051304b0a..0b26519ba7 100644 --- a/packager/media/formats/wvm/wvm_media_parser_unittest.cc +++ b/packager/media/formats/wvm/wvm_media_parser_unittest.cc @@ -52,7 +52,9 @@ class MockKeySource : public FixedKeySource { MockKeySource() {} ~MockKeySource() override {} - MOCK_METHOD1(FetchKeys, Status(uint32_t asset_id)); + MOCK_METHOD2(FetchKeys, + Status(EmeInitDataType init_data_type, + const std::vector& init_data)); MOCK_METHOD2(GetKey, Status(TrackType track_type, EncryptionKey* key)); @@ -185,7 +187,7 @@ TEST_F(WvmMediaParserTest, ParseWvmInitWithoutKeySource) { } TEST_F(WvmMediaParserTest, ParseWvm) { - EXPECT_CALL(*key_source_, FetchKeys(_)).WillOnce(Return(Status::OK)); + EXPECT_CALL(*key_source_, FetchKeys(_, _)).WillOnce(Return(Status::OK)); EXPECT_CALL(*key_source_, GetKey(_, _)) .WillOnce(DoAll(SetArgPointee<1>(encryption_key_), Return(Status::OK))); Parse(kWvmFile); @@ -196,7 +198,7 @@ TEST_F(WvmMediaParserTest, ParseWvm) { } TEST_F(WvmMediaParserTest, ParseWvmWith64ByteAssetKey) { - EXPECT_CALL(*key_source_, FetchKeys(_)).WillOnce(Return(Status::OK)); + EXPECT_CALL(*key_source_, FetchKeys(_, _)).WillOnce(Return(Status::OK)); // WVM uses only the first 16 bytes of the asset key. encryption_key_.key.resize(64); encryption_key_.key.assign(k64ByteAssetKey, k64ByteAssetKey + 64); @@ -209,7 +211,7 @@ TEST_F(WvmMediaParserTest, ParseWvmWith64ByteAssetKey) { } TEST_F(WvmMediaParserTest, ParseMultiConfigWvm) { - EXPECT_CALL(*key_source_, FetchKeys(_)).WillOnce(Return(Status::OK)); + EXPECT_CALL(*key_source_, FetchKeys(_, _)).WillOnce(Return(Status::OK)); EXPECT_CALL(*key_source_, GetKey(_, _)) .WillOnce(DoAll(SetArgPointee<1>(encryption_key_), Return(Status::OK))); Parse(kMultiConfigWvmFile);