Source release 14.0.0

This commit is contained in:
John W. Bruce
2018-05-16 17:35:40 -07:00
parent 31381a1311
commit 3ab70cec4e
2053 changed files with 1585838 additions and 4614 deletions

View File

@@ -81,6 +81,80 @@ const std::string kHlsInitData =
"lc3QiLA0KICAgImNvbnRlbnRfaWQiOiAiWW1sblluVmphMkoxYm01NSIsDQogICAia2V5X2lkc"
"yI6IFsNCiAgICAgICI5Yjc1OTA0MDMyMWE0MDhhNWM3NzY4YjQ1MTEyODdhNiINCiAgIF0NCn0"
"=\",IV=0x75537a79fa41abc7b598ea72aba0c26f";
const std::string kCencEntitlementInitData1 = a2bs_hex(
"000001fb" // blob size
"70737368" // "pssh"
"00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"000001db" // pssh data size
// pssh data:
"220b47726f7570563254657374381448"
"e3dc959b065002580272580a10668093"
"381a8c5be48a0168ce372726ac1210c8"
"326486bb5d5c4a958f00b1111afc811a"
"20082cd9d3aed3ebe6239d30fbcf0b22"
"1d28cbb0360ea1295c2363973346ec00"
"512210914781334e864c8eb7f768cf26"
"49073872580a10f872d11d5b1052f2bd"
"a94e60a0e383021210450897c987a85c"
"2e9579f968554a12991a2097e603ceea"
"f35ed8cef1029eae7a0a54701e3d6db6"
"80e7da1de3b22a8db347fb2210b41c34"
"29b7bb96972bbaf6587bc0ddf172580a"
"10bac58b9fce9e5929a42a180e529f19"
"4712103f11f22988d25659b145ce4854"
"3e6b141a20416e22768e5a57b08d155e"
"5210d00658056947ff06d626668bceb3"
"5eb01c6b57221081fb2ff3fef79d332f"
"f98be46233596972580a101261c8036d"
"ae5c8caa968858aa0ca9cc12106d583c"
"b37c1456519843a81cf49912221a20c2"
"1116bb54a226e8d879a4cd41d8879920"
"2ae85b80d83b1b4447e5d7fcad6f6a22"
"100b27a4c3f44771d2b0c7c34c66af35"
"b572580a10ab1c8c259c6b5967991389"
"65bff5ac0c1210b5b4473658565d3786"
"efaf4b85d8e6e21a203ce6a9085285c2"
"ece0b650dc83dd7aa8ac849611a8e3f8"
"3c8f389223c0f3621522101946f0c2a3"
"d543101cc842bbec2d0b30");
const std::string kCencEntitlementInitData2 = a2bs_hex(
"000001fb" // blob size
"70737368" // "pssh"
"00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"000001db" // pssh data size
// pssh data:
"220b47726f7570563254657374381548"
"e3dc959b065002580272580a10668093"
"381a8c5be48a0168ce372726ac1210f8"
"488775a99855ff94b93ec5bd4993561a"
"20d15ba631c20e95da0d4857f6a1d25a"
"a3bccbd3fde18b3fdc1dd8c4f0ede76f"
"402210d6dd3675f0d1150052e81b9107"
"6d7fc172580a10f872d11d5b1052f2bd"
"a94e60a0e383021210ad1f93ad921e53"
"b097c415b2bf1ef1c61a20b2087b60a2"
"d253ac2158a1bfa789b150b79701b29e"
"c852a2662560f8b8977a4c2210051ed3"
"2628671fbda58f506ba5ea713972580a"
"10bac58b9fce9e5929a42a180e529f19"
"47121027cdda7bfe5e5fd4bff2ebc9c7"
"c020701a20f2cb1184d648a2404517e6"
"7a39d698332aae6bb890a69bf7ddb536"
"75b8ac41c62210a80ed7f9b728fdd566"
"0b01b173ace26372580a101261c8036d"
"ae5c8caa968858aa0ca9cc1210769a70"
"0442a25bf5ae17174c70f4cb8e1a206c"
"7b2012723fc47c83b003ea214204915f"
"9a63dc373bf219f36ccf5697589aa422"
"10bcc3c16e836cca264d5493a0c334d3"
"4872580a10ab1c8c259c6b5967991389"
"65bff5ac0c1210894b04aef78557c6a7"
"e6e8855febbcc91a2025cc545ee3cd0c"
"c323586610ff6a8f8f22a78f5fade2f2"
"1083f152c52208f16d2210257aacacec"
"512a2e769396b10e6d9dfa");
// This Key ID must match the key retrieved from the license server by
// kCencInitData.
@@ -90,6 +164,12 @@ const std::vector<uint8_t> kKeyIdCtr = a2b_hex(
// kHlsInitData.
const std::vector<uint8_t> kKeyIdCbc = a2b_hex(
"9b759040321a408a5c7768b4511287a6");
// This Key ID must match a key embedded in kCencEntitlementInitData1.
const std::vector<uint8_t> kKeyIdEntitlement1 = a2b_hex(
"c8326486bb5d5c4a958f00b1111afc81");
// This Key ID must match a key embedded in kCencEntitlementInitData2.
const std::vector<uint8_t> kKeyIdEntitlement2 = a2b_hex(
"f8488775a99855ff94b93ec5bd499356");
// A default pattern object disables patterns during decryption.
const Cdm::Pattern kPatternNone;
@@ -118,8 +198,8 @@ class CdmTest : public Test, public Cdm::IEventListener {
void(const std::string& session_id,
Cdm::MessageType message_type,
const std::string& message));
MOCK_METHOD1(onKeyStatusesChange,
void(const std::string& session_id));
MOCK_METHOD2(onKeyStatusesChange,
void(const std::string& session_id, bool has_new_usable_key));
MOCK_METHOD1(onRemoveComplete,
void(const std::string& session_id));
MOCK_METHOD2(onDeferredComplete,
@@ -179,7 +259,7 @@ class CdmTest : public Test, public Cdm::IEventListener {
}
void CreateAdditionalCdm(bool privacy_mode, scoped_ptr<Cdm>* cdm) {
cdm->reset(Cdm::create(this, NULL, privacy_mode));
cdm->reset(Cdm::create(this, g_host, privacy_mode));
ASSERT_NE((Cdm*)0, cdm->get());
}
@@ -297,9 +377,9 @@ class CdmTest : public Test, public Cdm::IEventListener {
}
ASSERT_FALSE(init_data.empty());
EXPECT_CALL(*this, onMessage(*session_id, Cdm::kLicenseRequest, _)).
WillOnce(SaveArg<2>(message));
status = cdm_->generateRequest(*session_id, init_data_type, init_data);
EXPECT_CALL(*this, onMessage(*session_id, Cdm::kLicenseRequest, _))
.WillOnce(SaveArg<2>(message));
status = generateRequestWithRetry(*session_id, init_data_type, init_data);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
@@ -328,8 +408,8 @@ class CdmTest : public Test, public Cdm::IEventListener {
std::string response;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
session_type, init_data_type, session_id, &response));
EXPECT_CALL(*this, onKeyStatusesChange(*session_id));
Cdm::Status status = cdm_->update(*session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(*session_id, true));
Cdm::Status status = updateWithRetry(*session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
@@ -342,8 +422,8 @@ class CdmTest : public Test, public Cdm::IEventListener {
g_license_server, message, &response));
// This license should be accepted, but the keys are not expected to change.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
Cdm::Status status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
Cdm::Status status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
@@ -366,6 +446,41 @@ class CdmTest : public Test, public Cdm::IEventListener {
return reply;
}
// This calls cdm->update, and retries several times if there is a
// failure due to nonce flood errors.
Cdm::Status updateWithRetry(const std::string& session_id,
const std::string& response) {
const int num_retries = 5;
for (int i = 0; i < num_retries; i++) {
Cdm::Status status = cdm_->update(session_id, response);
if (status == Cdm::kQuotaExceeded) {
sleep(1);
continue;
}
return status;
}
return Cdm::kQuotaExceeded;
}
// This calls cdm->generateRequest, and retries several times if there is a
// failure due to nonce flood errors.
Cdm::Status generateRequestWithRetry(const std::string& session_id,
Cdm::InitDataType init_data_type,
const std::string& init_data) {
const int num_retries = 5;
for (int i = 0; i < num_retries; i++) {
LOGD("attempt %d", i);
Cdm::Status status =
cdm_->generateRequest(session_id, init_data_type, init_data);
if (status == Cdm::kQuotaExceeded) {
sleep(1);
continue;
}
return status;
}
return Cdm::kQuotaExceeded;
}
scoped_ptr<Cdm> cdm_;
};
@@ -599,7 +714,7 @@ TEST_F(CdmTest, Provision) {
// Creating a session should succeed.
std::string session_id;
Cdm::Status status;
status = cdm_->setServiceCertificate(g_license_service_certificate);
status = cdm_->setServiceCertificate(g_provisioning_service_certificate);
EXPECT_EQ(Cdm::kSuccess, status);
status = cdm_->createSession(Cdm::kTemporary, &session_id);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -608,7 +723,7 @@ TEST_F(CdmTest, Provision) {
std::string message;
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -617,7 +732,7 @@ TEST_F(CdmTest, Provision) {
ASSERT_FALSE(reply.empty());
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(1);
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
status = cdm_->update(session_id, reply);
status = updateWithRetry(session_id, reply);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
@@ -660,13 +775,13 @@ TEST_F(CdmTest, GenerateRequest) {
// Generate a license request for CENC.
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Can't call generateRequest more than once on a session.
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kInvalidState, status);
Mock::VerifyAndClear(this);
@@ -674,7 +789,7 @@ TEST_F(CdmTest, GenerateRequest) {
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _));
status = cdm_->generateRequest(session_id, Cdm::kWebM, kWebMInitData);
status = generateRequestWithRetry(session_id, Cdm::kWebM, kWebMInitData);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -682,7 +797,7 @@ TEST_F(CdmTest, GenerateRequest) {
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, Cdm::kKeyIds, kKeyIdsInitData);
status = generateRequestWithRetry(session_id, Cdm::kKeyIds, kKeyIdsInitData);
EXPECT_EQ(Cdm::kNotSupported, status);
Mock::VerifyAndClear(this);
@@ -690,7 +805,7 @@ TEST_F(CdmTest, GenerateRequest) {
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _));
status = cdm_->generateRequest(session_id, Cdm::kHls, kHlsInitData);
status = generateRequestWithRetry(session_id, Cdm::kHls, kHlsInitData);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -698,14 +813,14 @@ TEST_F(CdmTest, GenerateRequest) {
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, kBogusInitDataType, "asdf");
status = generateRequestWithRetry(session_id, kBogusInitDataType, "asdf");
EXPECT_EQ(Cdm::kTypeError, status);
Mock::VerifyAndClear(this);
// This same session should still be usable with a supported init data type
// after failing with an unsupported or bogus type.
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -713,7 +828,7 @@ TEST_F(CdmTest, GenerateRequest) {
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, Cdm::kCenc, "");
status = generateRequestWithRetry(session_id, Cdm::kCenc, "");
EXPECT_EQ(Cdm::kTypeError, status);
Mock::VerifyAndClear(this);
@@ -721,7 +836,8 @@ TEST_F(CdmTest, GenerateRequest) {
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, Cdm::kCenc, kInvalidCencInitData);
status =
generateRequestWithRetry(session_id, Cdm::kCenc, kInvalidCencInitData);
EXPECT_EQ(Cdm::kNotSupported, status);
Mock::VerifyAndClear(this);
@@ -729,14 +845,14 @@ TEST_F(CdmTest, GenerateRequest) {
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, Cdm::kCenc,
kNonWidevineCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc,
kNonWidevineCencInitData);
EXPECT_EQ(Cdm::kNotSupported, status);
Mock::VerifyAndClear(this);
// Try a bogus session ID.
EXPECT_CALL(*this, onMessage(_, _, _)).Times(0);
status = cdm_->generateRequest(kBogusSessionId, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(kBogusSessionId, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSessionNotFound, status);
Mock::VerifyAndClear(this);
}
@@ -757,23 +873,23 @@ TEST_F(CdmTest, Update) {
g_license_server, message, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = updateWithRetry(session_id, response);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Try updating a bogus session ID.
status = cdm_->update(kBogusSessionId, response);
status = updateWithRetry(kBogusSessionId, response);
EXPECT_EQ(Cdm::kSessionNotFound, status);
// Try updating with an empty response.
status = cdm_->update(session_id, "");
status = updateWithRetry(session_id, "");
EXPECT_EQ(Cdm::kTypeError, status);
// Create a new session and try updating before generating a request.
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->update(session_id, response);
status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kInvalidState, status);
}
@@ -789,7 +905,7 @@ TEST_F(CdmTest, Close) {
// Can't generate a license request after close.
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSessionNotFound, status);
Mock::VerifyAndClear(this);
@@ -813,8 +929,8 @@ TEST_F(CdmTest, LoadTemporary) {
Cdm::kTemporary, Cdm::kCenc, &session_id, &response));
// Update the temporary session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -837,22 +953,22 @@ TEST_F(CdmTest, DISABLED_LoadPersistent) {
Cdm::kPersistentLicense, Cdm::kCenc, &session_id, &response));
// Update the persistent session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Should be able to load the session again after closing it.
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Should be able to load the session again after recreating the CDM.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -861,7 +977,7 @@ TEST_F(CdmTest, DISABLED_LoadPersistent) {
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
g_host->Reset();
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSessionNotFound, status);
Mock::VerifyAndClear(this);
@@ -877,12 +993,12 @@ TEST_F(CdmTest, DISABLED_LoadWillFireExpiration) {
// Should be able to load the session again after recreating the CDM.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
ASSERT_EQ(Cdm::kSuccess, cdm_->load(session_id));
Mock::VerifyAndClear(this);
// Let the key expire, make sure we get a key status update.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _))
.Times(AtLeast(1));
g_host->ElapseTime(kOfflineLicenseDurationMs);
@@ -897,7 +1013,7 @@ TEST_F(CdmTest, DISABLED_PerOriginLoadPersistent) {
Cdm::kPersistentLicense, Cdm::kCenc, &session_id, &response));
// Update and close the persistent session.
Cdm::Status status = cdm_->update(session_id, response);
Cdm::Status status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
@@ -916,7 +1032,7 @@ TEST_F(CdmTest, DISABLED_PerOriginLoadPersistent) {
ASSERT_EQ(Cdm::kSuccess, status);
// Should not be able to load from another origin.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
status = other_cdm->load(session_id);
EXPECT_EQ(Cdm::kSessionNotFound, status);
Mock::VerifyAndClear(this);
@@ -931,8 +1047,8 @@ TEST_F(CdmTest, DISABLED_LoadUsageRecord) {
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
Cdm::Status status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
Cdm::Status status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -941,7 +1057,7 @@ TEST_F(CdmTest, DISABLED_LoadUsageRecord) {
ASSERT_EQ(Cdm::kSuccess, status);
// There should be no usable keys after loading this session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -949,7 +1065,7 @@ TEST_F(CdmTest, DISABLED_LoadUsageRecord) {
// Should be able to load the session again after recreating the CDM.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -959,7 +1075,7 @@ TEST_F(CdmTest, DISABLED_LoadUsageRecord) {
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
g_host->Reset();
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSessionNotFound, status);
@@ -974,8 +1090,8 @@ TEST_F(CdmTest, DISABLED_DestroyUsageRecord) {
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
Cdm::Status status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
Cdm::Status status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -984,7 +1100,7 @@ TEST_F(CdmTest, DISABLED_DestroyUsageRecord) {
ASSERT_EQ(Cdm::kSuccess, status);
// There should be no usable keys after loading this session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -992,7 +1108,7 @@ TEST_F(CdmTest, DISABLED_DestroyUsageRecord) {
// Should be able to load the session again after recreating the CDM.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->deleteUsageRecord(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -1009,8 +1125,8 @@ TEST_F(CdmTest, DISABLED_DestroyAllUsageRecords) {
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
Cdm::Status status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
Cdm::Status status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1019,7 +1135,7 @@ TEST_F(CdmTest, DISABLED_DestroyAllUsageRecords) {
ASSERT_EQ(Cdm::kSuccess, status);
// There should be no usable keys after loading this session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -1027,7 +1143,7 @@ TEST_F(CdmTest, DISABLED_DestroyAllUsageRecords) {
// Should be able to load the session again after recreating the CDM.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->deleteAllUsageRecords();
EXPECT_EQ(Cdm::kSuccess, status);
@@ -1044,8 +1160,8 @@ TEST_F(CdmTest, DISABLED_ListUsageRecords) {
Cdm::kPersistentUsageRecord, Cdm::kCenc, &session_id, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
Cdm::Status status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
Cdm::Status status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1054,7 +1170,7 @@ TEST_F(CdmTest, DISABLED_ListUsageRecords) {
ASSERT_EQ(Cdm::kSuccess, status);
// There should be no usable keys after loading this session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
@@ -1062,7 +1178,7 @@ TEST_F(CdmTest, DISABLED_ListUsageRecords) {
// Should be able to load the session again after recreating the CDM.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
std::vector<std::string> ksids;
@@ -1078,7 +1194,7 @@ TEST_F(CdmTest, DISABLED_ListUsageRecords) {
}
TEST_F(CdmTest, LoadBogus) {
EXPECT_CALL(*this, onKeyStatusesChange(_)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(_, _)).Times(0);
Cdm::Status status = cdm_->load(kBogusSessionId);
EXPECT_EQ(Cdm::kSessionNotFound, status);
}
@@ -1100,7 +1216,7 @@ TEST_F(CdmTest, GetKeyStatuses) {
EXPECT_EQ(expected_key_id, map.begin()->first);
// Let the key expire.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _)).Times(
AtLeast(1));
g_host->ElapseTime(kExpirationTestDelayMs);
@@ -1131,7 +1247,7 @@ TEST_F(CdmTest, GetExpiration) {
int64_t original_expiration = expiration;
// Let the key expire.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRenewal, _)).Times(
AtLeast(1));
g_host->ElapseTime(kExpirationTestDelayMs);
@@ -1159,7 +1275,7 @@ TEST_F(CdmTest, DISABLED_Remove) {
// Remove the session. This causes a release message to be generated.
std::string message;
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
Cdm::Status status = cdm_->remove(session_id);
@@ -1179,7 +1295,7 @@ TEST_F(CdmTest, DISABLED_Remove) {
// Update the session.
EXPECT_CALL(*this, onRemoveComplete(session_id));
status = cdm_->update(session_id, response);
status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1214,7 +1330,7 @@ TEST_F(CdmTest, DISABLED_RemoveUsageRecord) {
// Remove the session. This causes a release message to be generated.
std::string message;
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
Cdm::Status status = cdm_->remove(session_id);
@@ -1234,7 +1350,7 @@ TEST_F(CdmTest, DISABLED_RemoveUsageRecord) {
// Update the session.
EXPECT_CALL(*this, onRemoveComplete(session_id));
status = cdm_->update(session_id, response);
status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1251,7 +1367,7 @@ TEST_F(CdmTest, DISABLED_RemoveIncomplete) {
// Remove the session. This causes a release message to be generated.
std::string message;
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
Cdm::Status status = cdm_->remove(session_id);
@@ -1269,7 +1385,7 @@ TEST_F(CdmTest, DISABLED_RemoveIncomplete) {
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
// Load the partially removed session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->load(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
@@ -1282,7 +1398,7 @@ TEST_F(CdmTest, DISABLED_RemoveIncomplete) {
// Remove the session again to fire the release message.
message.clear();
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
status = cdm_->remove(session_id);
@@ -1296,9 +1412,9 @@ TEST_F(CdmTest, DISABLED_RemoveIncomplete) {
g_license_server, message, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onRemoveComplete(session_id));
status = cdm_->update(session_id, response);
status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1315,7 +1431,7 @@ TEST_F(CdmTest, DISABLED_RemoveUsageRecordIncomplete) {
// Remove the session. This causes a release message to be generated.
std::string message;
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
Cdm::Status status = cdm_->remove(session_id);
@@ -1333,7 +1449,7 @@ TEST_F(CdmTest, DISABLED_RemoveUsageRecordIncomplete) {
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
// Load the partially removed session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).Times(0);
status = cdm_->load(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
@@ -1341,7 +1457,7 @@ TEST_F(CdmTest, DISABLED_RemoveUsageRecordIncomplete) {
// Remove the session again to fire a release message.
message.clear();
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
status = cdm_->remove(session_id);
@@ -1360,9 +1476,9 @@ TEST_F(CdmTest, DISABLED_RemoveUsageRecordIncomplete) {
g_license_server, message, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, _)).Times(0);
EXPECT_CALL(*this, onRemoveComplete(session_id));
status = cdm_->update(session_id, response);
status = updateWithRetry(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1397,9 +1513,9 @@ TEST_F(CdmTest, RequestPersistentLicenseWithWrongInitData) {
ASSERT_EQ(Cdm::kSuccess, status);
std::string message;
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).WillOnce(
SaveArg<2>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _))
.WillOnce(SaveArg<2>(&message));
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1418,10 +1534,10 @@ TEST_F(CdmTest, DISABLED_RequestTemporaryLicenseWithWrongInitData) {
ASSERT_EQ(Cdm::kSuccess, status);
std::string message;
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).WillOnce(
SaveArg<2>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc,
kCencPersistentInitData);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _))
.WillOnce(SaveArg<2>(&message));
status =
generateRequestWithRetry(session_id, Cdm::kCenc, kCencPersistentInitData);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1431,8 +1547,8 @@ TEST_F(CdmTest, DISABLED_RequestTemporaryLicenseWithWrongInitData) {
g_license_server, message, &response));
// This license should not be accepted.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
status = cdm_->update(session_id, response);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, false));
status = updateWithRetry(session_id, response);
EXPECT_EQ(Cdm::kRangeError, status);
Mock::VerifyAndClear(this);
}
@@ -1524,9 +1640,9 @@ TEST_F(CdmTest, SetAppParameters) {
// Send a generate request to ensure the parameter is in the message.
std::string message;
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).WillOnce(
SaveArg<2>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _))
.WillOnce(SaveArg<2>(&message));
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSuccess, status);
EXPECT_TRUE(!message.empty() && message.find(kValue) != std::string::npos);
Mock::VerifyAndClear(this);
@@ -1583,6 +1699,99 @@ TEST_F(CdmTest, SetVideoResolutionOverflow) {
cdm_->close(session_id);
}
TEST_F(CdmTest, GetStatusForHdcpResolution) {
// Unfortunately, since we cannot mock the HDCP state, we cannot validate
// the validity of the values returned here, only that meaningful values are
// returned.
Cdm::KeyStatus key_status;
ASSERT_EQ(Cdm::kSuccess,
cdm_->getStatusForHdcpVersion(Cdm::kHdcp1_x, &key_status));
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
ASSERT_EQ(Cdm::kSuccess,
cdm_->getStatusForHdcpVersion(Cdm::kHdcp2_0, &key_status));
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
ASSERT_EQ(Cdm::kSuccess,
cdm_->getStatusForHdcpVersion(Cdm::kHdcp2_1, &key_status));
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
ASSERT_EQ(Cdm::kSuccess,
cdm_->getStatusForHdcpVersion(Cdm::kHdcp2_2, &key_status));
EXPECT_THAT(key_status, AnyOf(Cdm::kUsable, Cdm::kOutputRestricted));
}
TEST_F(CdmTest, HandlesKeyRotationWithOnlyOneLicenseRequest) {
std::string session_id;
// TODO(b/77152154):
// The CreateSessionAndX helpers need to be reworked so this function can use
// them.
ASSERT_EQ(Cdm::kSuccess,
cdm_->setServiceCertificate(g_license_service_certificate));
ASSERT_EQ(Cdm::kSuccess,
cdm_->createSession(Cdm::kTemporary, &session_id));
// Generate a license request for the 1st entitlement init data.
std::string license_request;
{
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _))
.WillOnce(SaveArg<2>(&license_request));
ASSERT_EQ(Cdm::kSuccess,
generateRequestWithRetry(session_id,
Cdm::kCenc,
kCencEntitlementInitData1));
Mock::VerifyAndClear(this);
}
// Send the request to the license server and receive the license response.
std::string license_response;
FetchLicense(g_license_server, license_request, &license_response);
// Update the session with the new keys.
{
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
ASSERT_EQ(Cdm::kSuccess,
updateWithRetry(session_id, license_response));
Mock::VerifyAndClear(this);
}
// Set up decrypt input and output.
Cdm::InputBuffer input;
input.data = kInput.data();
input.data_length = kInput.size();
input.encryption_scheme = Cdm::kAesCtr;
input.pattern = kPatternNone;
Cdm::OutputBuffer output;
std::vector<uint8_t> output_buffer(input.data_length);
output.data = &(output_buffer[0]);
output.data_length = output_buffer.size();
// Attempt decrypt with a key from the first license.
input.key_id = kKeyIdEntitlement1.data();
input.key_id_length = kKeyIdEntitlement1.size();
input.iv = kIvEntitlement1.data();
input.iv_length = kIvEntitlement1.size();
ASSERT_EQ(Cdm::kSuccess, cdm_->decrypt(input, output));
EXPECT_EQ(kOutputEntitlement1, output_buffer);
// Load the second entitlement license using the first. This should not
// require any server roundtrip.
ASSERT_EQ(Cdm::kSuccess,
cdm_->load(session_id, Cdm::kCenc, kCencEntitlementInitData2));
// Attempt decrypt with a key from the second license.
input.key_id = kKeyIdEntitlement2.data();
input.key_id_length = kKeyIdEntitlement2.size();
input.iv = kIvEntitlement2.data();
input.iv_length = kIvEntitlement2.size();
ASSERT_EQ(Cdm::kSuccess, cdm_->decrypt(input, output));
EXPECT_EQ(kOutputEntitlement2, output_buffer);
}
// TODO(http://b/37286053): Fix this test.
TEST_P(CdmTestWithDecryptParam, DecryptToClearBuffer) {
DecryptParam param = GetParam();
@@ -1695,7 +1904,7 @@ TEST_F(CdmIndividualizationTest, BasicFlow) {
std::string message;
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1704,7 +1913,7 @@ TEST_F(CdmIndividualizationTest, BasicFlow) {
ASSERT_FALSE(reply.empty());
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(1);
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
status = cdm_->update(session_id, reply);
status = updateWithRetry(session_id, reply);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1715,8 +1924,8 @@ TEST_F(CdmIndividualizationTest, BasicFlow) {
// Acquire a license and update the session.
ASSERT_NO_FATAL_FAILURE(FetchLicense(
g_license_server, message, &reply));
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
status = cdm_->update(session_id, reply);
EXPECT_CALL(*this, onKeyStatusesChange(session_id, true));
status = updateWithRetry(session_id, reply);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
@@ -1738,7 +1947,7 @@ TEST_F(CdmIndividualizationTest, IsProvisioned) {
std::string message;
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1747,7 +1956,7 @@ TEST_F(CdmIndividualizationTest, IsProvisioned) {
ASSERT_FALSE(reply.empty());
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(1);
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
status = cdm_->update(session_id, reply);
status = updateWithRetry(session_id, reply);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1772,7 +1981,7 @@ TEST_F(CdmIndividualizationTest, RemoveProvisioning) {
std::string message;
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
status = generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1781,7 +1990,7 @@ TEST_F(CdmIndividualizationTest, RemoveProvisioning) {
ASSERT_FALSE(reply.empty());
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(1);
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
status = cdm_->update(session_id, reply);
status = updateWithRetry(session_id, reply);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1807,7 +2016,7 @@ TEST_F(CdmIndividualizationTest, WillNotSendRequestTwice) {
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
ASSERT_EQ(Cdm::kSuccess,
cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData));
generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData));
Mock::VerifyAndClear(this);
// Create a second session.
@@ -1817,7 +2026,7 @@ TEST_F(CdmIndividualizationTest, WillNotSendRequestTwice) {
// Should not get another individualization request.
EXPECT_CALL(*this, onMessage(_, _, _)).Times(0);
ASSERT_EQ(Cdm::kDeferred,
cdm_->generateRequest(session_id2, Cdm::kCenc, kCencInitData));
generateRequestWithRetry(session_id2, Cdm::kCenc, kCencInitData));
Mock::VerifyAndClear(this);
// Complete the provisioning request, should generate requests for both
@@ -1827,7 +2036,7 @@ TEST_F(CdmIndividualizationTest, WillNotSendRequestTwice) {
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(1);
EXPECT_CALL(*this, onMessage(session_id2, Cdm::kLicenseRequest, _)).Times(1);
EXPECT_CALL(*this, onDeferredComplete(session_id2, Cdm::kSuccess)).Times(1);
EXPECT_EQ(Cdm::kSuccess, cdm_->update(session_id, reply));
EXPECT_EQ(Cdm::kSuccess, updateWithRetry(session_id, reply));
Mock::VerifyAndClear(this);
}
@@ -1847,7 +2056,7 @@ TEST_F(CdmIndividualizationTest,
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
ASSERT_EQ(Cdm::kSuccess,
cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData));
generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData));
Mock::VerifyAndClear(this);
// Create a second session, don't call generateRequest for it.
@@ -1861,13 +2070,13 @@ TEST_F(CdmIndividualizationTest,
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(1);
EXPECT_CALL(*this, onMessage(session_id2, Cdm::kLicenseRequest, _)).Times(0);
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
EXPECT_EQ(Cdm::kSuccess, cdm_->update(session_id, reply));
EXPECT_EQ(Cdm::kSuccess, updateWithRetry(session_id, reply));
Mock::VerifyAndClear(this);
// We should get a license message for the second session.
EXPECT_CALL(*this, onMessage(session_id2, Cdm::kLicenseRequest, _)).Times(1);
ASSERT_EQ(Cdm::kSuccess,
cdm_->generateRequest(session_id2, Cdm::kCenc, kCencInitData));
generateRequestWithRetry(session_id2, Cdm::kCenc, kCencInitData));
Mock::VerifyAndClear(this);
}
@@ -1885,8 +2094,8 @@ TEST_F(CdmIndividualizationTest, PropagatesErrorsInUpdate) {
std::string message;
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
ASSERT_EQ(Cdm::kSuccess, cdm_->generateRequest(session_id, Cdm::kCenc,
kInvalidCencInitData));
ASSERT_EQ(Cdm::kSuccess, generateRequestWithRetry(session_id, Cdm::kCenc,
kInvalidCencInitData));
Mock::VerifyAndClear(this);
// Complete the provisioning request, should get an error call.
@@ -1894,7 +2103,7 @@ TEST_F(CdmIndividualizationTest, PropagatesErrorsInUpdate) {
ASSERT_FALSE(reply.empty());
EXPECT_CALL(*this, onMessage(_, _, _)).Times(0);
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
EXPECT_EQ(Cdm::kNotSupported, cdm_->update(session_id, reply));
EXPECT_EQ(Cdm::kNotSupported, updateWithRetry(session_id, reply));
Mock::VerifyAndClear(this);
}
@@ -1913,15 +2122,14 @@ TEST_F(CdmIndividualizationTest, OnlyPropagatesErrorsForThisSession) {
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
ASSERT_EQ(Cdm::kSuccess,
cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData));
generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData));
Mock::VerifyAndClear(this);
// Create another session that will cause an error.
std::string session_id_2;
ASSERT_EQ(Cdm::kSuccess,
cdm_->createSession(Cdm::kTemporary, &session_id_2));
ASSERT_EQ(Cdm::kDeferred, cdm_->generateRequest(session_id_2, Cdm::kCenc,
kInvalidCencInitData));
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id_2));
ASSERT_EQ(Cdm::kDeferred, generateRequestWithRetry(session_id_2, Cdm::kCenc,
kInvalidCencInitData));
// Complete the provisioning request, should succeed, but get an error
// callback.
@@ -1931,7 +2139,7 @@ TEST_F(CdmIndividualizationTest, OnlyPropagatesErrorsForThisSession) {
EXPECT_CALL(*this, onMessage(session_id_2, _, _)).Times(0);
EXPECT_CALL(*this, onDeferredComplete(session_id_2, Cdm::kNotSupported))
.Times(1);
EXPECT_EQ(Cdm::kSuccess, cdm_->update(session_id, reply));
EXPECT_EQ(Cdm::kSuccess, updateWithRetry(session_id, reply));
Mock::VerifyAndClear(this);
}
@@ -1962,7 +2170,7 @@ TEST_F(CdmIndividualizationTest, DISABLED_WorksWithLoad) {
// Because we are now provisioned with a new key, we can't load the session,
// but we will still be provisioned.
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
EXPECT_EQ(Cdm::kUnexpectedError, cdm_->update(session_id, reply));
EXPECT_EQ(Cdm::kUnexpectedError, updateWithRetry(session_id, reply));
Mock::VerifyAndClear(this);
// Create a second session, we should be previsioned at this point.
@@ -1970,7 +2178,7 @@ TEST_F(CdmIndividualizationTest, DISABLED_WorksWithLoad) {
ASSERT_EQ(Cdm::kSuccess, cdm_->createSession(Cdm::kTemporary, &session_id2));
EXPECT_CALL(*this, onMessage(session_id2, Cdm::kLicenseRequest, _)).Times(1);
ASSERT_EQ(Cdm::kSuccess,
cdm_->generateRequest(session_id2, Cdm::kCenc, kCencInitData));
generateRequestWithRetry(session_id2, Cdm::kCenc, kCencInitData));
Mock::VerifyAndClear(this);
}
@@ -1989,13 +2197,13 @@ TEST_F(CdmIndividualizationTest, WillResendOnProvisioningError) {
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id, _))
.WillOnce(SaveArg<1>(&message));
ASSERT_EQ(Cdm::kSuccess,
cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData));
generateRequestWithRetry(session_id, Cdm::kCenc, kCencInitData));
Mock::VerifyAndClear(this);
// Fail to provision the device.
EXPECT_CALL(*this, onMessage(_, _, _)).Times(0);
EXPECT_CALL(*this, onDeferredComplete(_, _)).Times(0);
EXPECT_EQ(Cdm::kUnexpectedError, cdm_->update(session_id, ""));
EXPECT_EQ(Cdm::kUnexpectedError, updateWithRetry(session_id, ""));
Mock::VerifyAndClear(this);
// Should get another individualization request.
@@ -2005,7 +2213,7 @@ TEST_F(CdmIndividualizationTest, WillResendOnProvisioningError) {
EXPECT_CALL(*this, onDirectIndividualizationRequest(session_id_2, _))
.WillOnce(SaveArg<1>(&message));
ASSERT_EQ(Cdm::kSuccess,
cdm_->generateRequest(session_id_2, Cdm::kCenc, kCencInitData));
generateRequestWithRetry(session_id_2, Cdm::kCenc, kCencInitData));
Mock::VerifyAndClear(this);
}