Source release v3.0.4

This commit is contained in:
Joey Parrish
2015-12-14 10:01:38 -08:00
parent 3d5571eaa1
commit 973eb25a17
21 changed files with 734 additions and 191 deletions

View File

@@ -142,6 +142,11 @@ class CdmTest : public Test,
// Clear anything stored, load default device cert.
g_host->Reset();
// Clear anything stored by OEMCrypto.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize());
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_DeleteUsageTable());
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Terminate());
// Reinit the library.
Cdm::DeviceCertificateRequest cert_request;
Cdm::Status status = Cdm::initialize(
@@ -230,61 +235,40 @@ class CdmTest : public Test,
if (ok) ASSERT_EQ(expected_status_code, status_code);
}
void CreateTemporarySessionAndGenerateRequest(std::string* session_id,
std::string* message) {
Cdm::Status status = cdm_->createSession(Cdm::kTemporary, session_id);
void CreateSessionAndGenerateRequest(Cdm::SessionType session_type,
std::string* session_id,
std::string* message) {
Cdm::Status status = cdm_->createSession(session_type, session_id);
ASSERT_EQ(Cdm::kSuccess, status);
std::string init_data;
if (session_type == Cdm::kTemporary) {
init_data = kCencInitData;
} else {
init_data = kCencPersistentInitData;
}
EXPECT_CALL(*this, onMessage(*session_id, Cdm::kLicenseRequest, _)).
WillOnce(SaveArg<2>(message));
status = cdm_->generateRequest(*session_id, Cdm::kCenc, kCencInitData);
status = cdm_->generateRequest(*session_id, Cdm::kCenc, init_data);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
void CreatePersistentSessionAndGenerateRequest(std::string* session_id,
std::string* message) {
Cdm::Status status = cdm_->createSession(Cdm::kPersistent, session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(*session_id, Cdm::kLicenseRequest, _)).
WillOnce(SaveArg<2>(message));
status = cdm_->generateRequest(*session_id, Cdm::kCenc,
kCencPersistentInitData);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
void CreateTemporarySessionAndFetchLicense(std::string* session_id,
std::string* response) {
void CreateSessionAndFetchLicense(Cdm::SessionType session_type,
std::string* session_id,
std::string* response) {
std::string message;
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndGenerateRequest(
session_id, &message));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndGenerateRequest(
session_type, session_id, &message));
FetchLicense(message, response);
}
void CreatePersistentSessionAndFetchLicense(std::string* session_id,
std::string* response) {
std::string message;
ASSERT_NO_FATAL_FAILURE(CreatePersistentSessionAndGenerateRequest(
session_id, &message));
FetchLicense(message, response);
}
void CreateTemporarySessionAndUpdate(std::string* session_id) {
void CreateSessionAndUpdate(Cdm::SessionType session_type,
std::string* session_id) {
std::string response;
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndFetchLicense(
session_id, &response));
EXPECT_CALL(*this, onKeyStatusesChange(*session_id));
Cdm::Status status = cdm_->update(*session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
void CreatePersistentSessionAndUpdate(std::string* session_id) {
std::string response;
ASSERT_NO_FATAL_FAILURE(CreatePersistentSessionAndFetchLicense(
session_id, &response));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
session_type, session_id, &response));
EXPECT_CALL(*this, onKeyStatusesChange(*session_id));
Cdm::Status status = cdm_->update(*session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
@@ -352,7 +336,7 @@ TEST_F(CdmTest, Initialize) {
static_cast<Cdm::SecureOutputType>(-1), PropertiesCE::GetClientInfo(),
g_host, g_host, g_host, &cert_request,
static_cast<Cdm::LogLevel>(g_cutoff));
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
// Try with various client info properties missing.
Cdm::ClientInfo working_client_info = PropertiesCE::GetClientInfo();
@@ -364,7 +348,7 @@ TEST_F(CdmTest, Initialize) {
Cdm::kNoSecureOutput, broken_client_info,
g_host, g_host, g_host, &cert_request,
static_cast<Cdm::LogLevel>(g_cutoff));
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
broken_client_info = working_client_info;
broken_client_info.company_name.clear();
@@ -372,7 +356,7 @@ TEST_F(CdmTest, Initialize) {
Cdm::kNoSecureOutput, broken_client_info,
g_host, g_host, g_host, &cert_request,
static_cast<Cdm::LogLevel>(g_cutoff));
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
broken_client_info = working_client_info;
broken_client_info.device_name.clear(); // Not required
@@ -388,7 +372,7 @@ TEST_F(CdmTest, Initialize) {
Cdm::kNoSecureOutput, broken_client_info,
g_host, g_host, g_host, &cert_request,
static_cast<Cdm::LogLevel>(g_cutoff));
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
broken_client_info = working_client_info;
broken_client_info.arch_name.clear(); // Not required
@@ -411,25 +395,25 @@ TEST_F(CdmTest, Initialize) {
Cdm::kNoSecureOutput, working_client_info,
NULL, g_host, g_host, &cert_request,
static_cast<Cdm::LogLevel>(g_cutoff));
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
status = Cdm::initialize(
Cdm::kNoSecureOutput, working_client_info,
g_host, NULL, g_host, &cert_request,
static_cast<Cdm::LogLevel>(g_cutoff));
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
status = Cdm::initialize(
Cdm::kNoSecureOutput, working_client_info,
g_host, g_host, NULL, &cert_request,
static_cast<Cdm::LogLevel>(g_cutoff));
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
status = Cdm::initialize(
Cdm::kNoSecureOutput, working_client_info,
g_host, g_host, g_host, NULL,
static_cast<Cdm::LogLevel>(g_cutoff));
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
// One last init with everything correct and working.
status = Cdm::initialize(
@@ -502,11 +486,11 @@ TEST_F(CdmTest, SetServerCertificate) {
// It is invalid to set an empty cert.
status = cdm_->setServerCertificate("");
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
// It is invalid to set a malformed cert.
status = cdm_->setServerCertificate("asdf");
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
}
TEST_F(CdmTest, CreateSession) {
@@ -524,12 +508,12 @@ TEST_F(CdmTest, CreateSession) {
EXPECT_NE(original_session_id, session_id);
// Create a persistent session.
status = cdm_->createSession(Cdm::kPersistent, &session_id);
status = cdm_->createSession(Cdm::kPersistentLicense, &session_id);
EXPECT_EQ(Cdm::kSuccess, status);
// Try a NULL pointer for session ID.
status = cdm_->createSession(Cdm::kTemporary, NULL);
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
// Try a bogus session type.
status = cdm_->createSession(kBogusSessionType, &session_id);
@@ -574,7 +558,7 @@ TEST_F(CdmTest, GenerateRequest) {
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, kBogusInitDataType, "asdf");
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
Mock::VerifyAndClear(this);
// This same session should still be usable with a supported init data type
@@ -589,7 +573,7 @@ TEST_F(CdmTest, GenerateRequest) {
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).Times(0);
status = cdm_->generateRequest(session_id, Cdm::kCenc, "");
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
Mock::VerifyAndClear(this);
// Try to pass invalid CENC init data.
@@ -619,8 +603,8 @@ TEST_F(CdmTest, GenerateRequest) {
TEST_F(CdmTest, Update) {
std::string session_id;
std::string message;
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndGenerateRequest(
&session_id, &message));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndGenerateRequest(
Cdm::kTemporary, &session_id, &message));
// Acquire a license.
std::string response;
@@ -638,7 +622,7 @@ TEST_F(CdmTest, Update) {
// Try updating with an empty response.
status = cdm_->update(session_id, "");
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kTypeError, status);
// Create a new session and try updating before generating a request.
status = cdm_->createSession(Cdm::kTemporary, &session_id);
@@ -675,8 +659,8 @@ TEST_F(CdmTest, Close) {
TEST_F(CdmTest, LoadTemporary) {
std::string session_id;
std::string response;
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndFetchLicense(
&session_id, &response));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
Cdm::kTemporary, &session_id, &response));
// Update the temporary session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
@@ -696,8 +680,8 @@ TEST_F(CdmTest, LoadTemporary) {
TEST_F(CdmTest, LoadPersistent) {
std::string session_id;
std::string response;
ASSERT_NO_FATAL_FAILURE(CreatePersistentSessionAndFetchLicense(
&session_id, &response));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
Cdm::kPersistentLicense, &session_id, &response));
// Update the persistent session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
@@ -731,6 +715,49 @@ TEST_F(CdmTest, LoadPersistent) {
Mock::VerifyAndClear(this);
}
TEST_F(CdmTest, LoadUsageRecord) {
std::string session_id;
std::string response;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndFetchLicense(
Cdm::kPersistentUsageRecord, &session_id, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
Cdm::Status status = cdm_->update(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);
// There should be no usable keys after loading this session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _));
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 */));
ASSERT_NO_FATAL_FAILURE(SetDefaultServerCertificate());
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _));
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Should not be able to load the session again clearing storage.
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
g_host->Reset();
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);
Mock::VerifyAndClear(this);
}
TEST_F(CdmTest, LoadBogus) {
EXPECT_CALL(*this, onKeyStatusesChange(_)).Times(0);
Cdm::Status status = cdm_->load(kBogusSessionId);
@@ -739,7 +766,7 @@ TEST_F(CdmTest, LoadBogus) {
TEST_F(CdmTest, GetKeyStatuses) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndUpdate(&session_id));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kTemporary, &session_id));
// We should be able to query status and see a usable key.
Cdm::KeyStatusMap map;
@@ -773,7 +800,7 @@ TEST_F(CdmTest, GetKeyStatuses) {
TEST_F(CdmTest, GetExpiration) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndUpdate(&session_id));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kTemporary, &session_id));
// We should be able to query expiration and get a value in the future.
int64_t expiration;
@@ -805,7 +832,8 @@ TEST_F(CdmTest, GetExpiration) {
TEST_F(CdmTest, Remove) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreatePersistentSessionAndUpdate(&session_id));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, &session_id));
// Remove the session. This causes a release message to be generated.
std::string message;
@@ -820,7 +848,7 @@ TEST_F(CdmTest, Remove) {
Cdm::KeyStatusMap map;
status = cdm_->getKeyStatuses(session_id, &map);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_EQ(Cdm::kExpired, map.begin()->second);
EXPECT_EQ(Cdm::kReleased, map.begin()->second);
// Post the release message to the license server.
std::string response;
@@ -843,20 +871,56 @@ TEST_F(CdmTest, Remove) {
EXPECT_EQ(Cdm::kSessionNotFound, status);
// Try a new session.
status = cdm_->createSession(Cdm::kPersistent, &session_id);
status = cdm_->createSession(Cdm::kPersistentLicense, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->remove(session_id);
EXPECT_EQ(Cdm::kInvalidState, status);
// Try a temporary session.
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndUpdate(&session_id));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kTemporary, &session_id));
status = cdm_->remove(session_id);
EXPECT_EQ(Cdm::kInvalidAccess, status);
EXPECT_EQ(Cdm::kRangeError, status);
}
TEST_F(CdmTest, RemoveUsageRecord) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentUsageRecord, &session_id));
// Remove the session. This causes a release message to be generated.
std::string message;
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
Cdm::Status status = cdm_->remove(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// The keys should already be unusable.
Cdm::KeyStatusMap map;
status = cdm_->getKeyStatuses(session_id, &map);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_EQ(Cdm::kReleased, map.begin()->second);
// Post the release message to the license server.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(message, &response));
// Update the session.
EXPECT_CALL(*this, onRemoveComplete(session_id));
status = cdm_->update(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// The session is now completely gone.
status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSessionNotFound, status);
}
TEST_F(CdmTest, RemoveIncomplete) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreatePersistentSessionAndUpdate(&session_id));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, &session_id));
// Remove the session. This causes a release message to be generated.
std::string message;
@@ -872,7 +936,64 @@ TEST_F(CdmTest, RemoveIncomplete) {
status = cdm_->getKeyStatuses(session_id, &map);
ASSERT_EQ(Cdm::kSuccess, status);
ASSERT_FALSE(map.empty());
EXPECT_EQ(Cdm::kExpired, map.begin()->second);
EXPECT_EQ(Cdm::kReleased, map.begin()->second);
// Recreate the CDM.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
ASSERT_NO_FATAL_FAILURE(SetDefaultServerCertificate());
// Load the partially removed session, which will immediately generate a
// release message.
message.clear();
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
status = cdm_->load(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
ASSERT_FALSE(message.empty());
Mock::VerifyAndClear(this);
// This session has no keys.
status = cdm_->getKeyStatuses(session_id, &map);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_TRUE(map.empty());
// Post the release message to the license server.
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(message, &response));
// Update the session.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
EXPECT_CALL(*this, onRemoveComplete(session_id));
status = cdm_->update(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// The session is now completely gone.
status = cdm_->load(session_id);
ASSERT_EQ(Cdm::kSessionNotFound, status);
}
TEST_F(CdmTest, RemoveUsageRecordIncomplete) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentUsageRecord, &session_id));
// Remove the session. This causes a release message to be generated.
std::string message;
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRelease, _)).WillOnce(
SaveArg<2>(&message));
Cdm::Status status = cdm_->remove(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// The keys should already be unusable, but they should still exist.
Cdm::KeyStatusMap map;
status = cdm_->getKeyStatuses(session_id, &map);
ASSERT_EQ(Cdm::kSuccess, status);
ASSERT_FALSE(map.empty());
EXPECT_EQ(Cdm::kReleased, map.begin()->second);
// Recreate the CDM.
ASSERT_NO_FATAL_FAILURE(RecreateCdm(true /* privacy_mode */));
@@ -913,7 +1034,8 @@ TEST_F(CdmTest, RemoveIncomplete) {
TEST_F(CdmTest, RemoveNotLoaded) {
// Create a persistent session and then close it.
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreatePersistentSessionAndUpdate(&session_id));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(
Cdm::kPersistentLicense, &session_id));
Cdm::Status status = cdm_->close(session_id);
ASSERT_EQ(Cdm::kSuccess, status);
@@ -945,7 +1067,7 @@ TEST_F(CdmTest, DecryptClear) {
// Create a session with the right keys.
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndUpdate(&session_id));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kTemporary, &session_id));
// Decrypt should now succeed.
status = cdm_->decrypt(input, output);
@@ -958,7 +1080,8 @@ TEST_F(CdmTest, RequestPersistentLicenseWithWrongInitData) {
// Generate a request for a persistent license without using the correct
// persistent content init data.
std::string session_id;
Cdm::Status status = cdm_->createSession(Cdm::kPersistent, &session_id);
Cdm::Status status = cdm_->createSession(Cdm::kPersistentLicense,
&session_id);
ASSERT_EQ(Cdm::kSuccess, status);
std::string message;
@@ -990,24 +1113,16 @@ TEST_F(CdmTest, RequestTemporaryLicenseWithWrongInitData) {
std::string response;
ASSERT_NO_FATAL_FAILURE(FetchLicense(message, &response));
// This license should be accepted.
// This license should not be accepted.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
status = cdm_->update(session_id, response);
EXPECT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Should not 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)).Times(0);
status = cdm_->load(session_id);
EXPECT_EQ(Cdm::kSessionNotFound, status);
EXPECT_EQ(Cdm::kRangeError, status);
Mock::VerifyAndClear(this);
}
TEST_F(CdmTest, Renewal) {
std::string session_id;
ASSERT_NO_FATAL_FAILURE(CreateTemporarySessionAndUpdate(&session_id));
ASSERT_NO_FATAL_FAILURE(CreateSessionAndUpdate(Cdm::kTemporary, &session_id));
// We should have a timer.
EXPECT_NE(0, g_host->NumTimers());
@@ -1044,9 +1159,10 @@ TEST_F(CdmTest, ServerCertificateProvisioning) {
Cdm::Status status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
// Expect an individualization request.
// Expect a license request type message, but this is actually a server cert
// provisioning request.
std::string message;
EXPECT_CALL(*this, onMessage(session_id, Cdm::kIndividualizationRequest, _)).
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).
WillOnce(SaveArg<2>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
ASSERT_EQ(Cdm::kSuccess, status);
@@ -1058,7 +1174,7 @@ TEST_F(CdmTest, ServerCertificateProvisioning) {
// No keys will change, since this wasn't a license.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
// We should get an actual license request generated during update.
// We should get another license request generated during update.
message.clear();
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).WillOnce(
SaveArg<2>(&message));
@@ -1076,7 +1192,7 @@ TEST_F(CdmTest, ServerCertificateProvisioning) {
ASSERT_NO_FATAL_FAILURE(FetchLicense(message, &response));
// Update the session. The keys will change now.
EXPECT_CALL(*this, onKeyStatusesChange(session_id));
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(1);
status = cdm_->update(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
@@ -1087,17 +1203,30 @@ TEST_F(CdmTest, ServerCertificateProvisioning) {
ASSERT_FALSE(map.empty());
EXPECT_EQ(Cdm::kUsable, map.begin()->second);
// Create another session. This one should not require server certificate
// provisioning.
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
// Expect a license request, not an individualization request.
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _));
// Expect a license request.
message.clear();
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).WillOnce(
SaveArg<2>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Relay it to the server.
ASSERT_NO_FATAL_FAILURE(FetchLicense(message, &response));
// Keys will change, since this was an actual license.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(1);
status = cdm_->update(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Create a second CDM instance.
scoped_ptr<Cdm> cdm2;
CreateAdditionalCdm(true /* privacy_mode */, &cdm2);
@@ -1107,20 +1236,45 @@ TEST_F(CdmTest, ServerCertificateProvisioning) {
// instances.
status = cdm2->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kIndividualizationRequest, _));
message.clear();
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).WillOnce(
SaveArg<2>(&message));
status = cdm2->generateRequest(session_id, Cdm::kCenc, kCencInitData);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Relay it to the server.
ASSERT_NO_FATAL_FAILURE(FetchLicense(message, &response));
// No keys will change, since this wasn't a license.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(0);
// We should get another license request generated during update.
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _));
status = cdm2->update(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Create another session on the first CDM. This one should not require
// server certificate provisioning. This proves that the creation of the
// second CDM instance did not affect the state of the first.
status = cdm_->createSession(Cdm::kTemporary, &session_id);
ASSERT_EQ(Cdm::kSuccess, status);
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _));
message.clear();
EXPECT_CALL(*this, onMessage(session_id, Cdm::kLicenseRequest, _)).WillOnce(
SaveArg<2>(&message));
status = cdm_->generateRequest(session_id, Cdm::kCenc, kCencInitData);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
// Relay it to the server.
ASSERT_NO_FATAL_FAILURE(FetchLicense(message, &response));
// Keys will change, since this was an actual license.
EXPECT_CALL(*this, onKeyStatusesChange(session_id)).Times(1);
status = cdm_->update(session_id, response);
ASSERT_EQ(Cdm::kSuccess, status);
Mock::VerifyAndClear(this);
}
TEST_F(CdmTest, SetAppParameters) {
@@ -1140,19 +1294,19 @@ TEST_F(CdmTest, SetAppParameters) {
// Try to get using a null result.
status = cdm_->getAppParameter(kParamName, NULL);
ASSERT_EQ(Cdm::kInvalidAccess, status);
ASSERT_EQ(Cdm::kTypeError, status);
// Try to get using an empty key.
status = cdm_->getAppParameter("", &result);
ASSERT_EQ(Cdm::kInvalidAccess, status);
ASSERT_EQ(Cdm::kTypeError, status);
// Try to set using an empty key.
status = cdm_->setAppParameter("", kValue);
ASSERT_EQ(Cdm::kInvalidAccess, status);
ASSERT_EQ(Cdm::kTypeError, status);
// Try to remove using an empty key.
status = cdm_->removeAppParameter("");
ASSERT_EQ(Cdm::kInvalidAccess, status);
ASSERT_EQ(Cdm::kTypeError, status);
// Change an existing app parameter.
status = cdm_->setAppParameter(kParamName, kNewValue);
@@ -1165,11 +1319,11 @@ TEST_F(CdmTest, SetAppParameters) {
status = cdm_->removeAppParameter(kParamName);
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->getAppParameter(kParamName, &result);
ASSERT_EQ(Cdm::kInvalidAccess, status);
ASSERT_EQ(Cdm::kTypeError, status);
// Try to remove an absent value.
status = cdm_->removeAppParameter(kParamName2);
ASSERT_EQ(Cdm::kInvalidAccess, status);
ASSERT_EQ(Cdm::kTypeError, status);
// Set some values to check for.
status = cdm_->setAppParameter(kParamName, kValue);
@@ -1198,9 +1352,9 @@ TEST_F(CdmTest, SetAppParameters) {
status = cdm_->clearAppParameters();
ASSERT_EQ(Cdm::kSuccess, status);
status = cdm_->getAppParameter(kParamName, &result);
ASSERT_EQ(Cdm::kInvalidAccess, status);
ASSERT_EQ(Cdm::kTypeError, status);
status = cdm_->getAppParameter(kParamName2, &result);
ASSERT_EQ(Cdm::kInvalidAccess, status);
ASSERT_EQ(Cdm::kTypeError, status);
}
} // namespace widevine

View File

@@ -32,7 +32,7 @@ void PrintTo(const Cdm::Status& value, ::std::ostream* os) {
break;
case Cdm::kNoKey: *os << "Cdm::kNoKey";
break;
case Cdm::kInvalidAccess: *os << "Cdm::kInvalidAccess";
case Cdm::kTypeError: *os << "Cdm::kTypeError";
break;
case Cdm::kNotSupported: *os << "Cdm::kNotSupported";
break;
@@ -40,6 +40,8 @@ void PrintTo(const Cdm::Status& value, ::std::ostream* os) {
break;
case Cdm::kQuotaExceeded: *os << "Cdm::kQuotaExceeded";
break;
case Cdm::kRangeError: *os << "Cdm::kRangeError";
break;
case Cdm::kUnexpectedError: *os << "Cdm::kUnexpectedError";
break;
default: *os << "Unknown Cdm::Status value " << value;
@@ -53,7 +55,7 @@ void PrintTo(const Cdm::KeyStatus& value, ::std::ostream* os) {
break;
case Cdm::kExpired: *os << "Cdm::kExpired";
break;
case Cdm::kOutputNotAllowed: *os << "Cdm::kOutputNotAllowed";
case Cdm::kOutputRestricted: *os << "Cdm::kOutputRestricted";
break;
case Cdm::kStatusPending: *os << "Cdm::kStatusPending";
break;