diff --git a/libwvdrmengine/cdm/core/include/certificate_provisioning.h b/libwvdrmengine/cdm/core/include/certificate_provisioning.h index 219a9d99..1468f204 100644 --- a/libwvdrmengine/cdm/core/include/certificate_provisioning.h +++ b/libwvdrmengine/cdm/core/include/certificate_provisioning.h @@ -26,7 +26,7 @@ class ServiceCertificate; class CertificateProvisioning { public: CertificateProvisioning(metrics::CryptoMetrics* metrics) : - crypto_session_(metrics), + crypto_session_(CryptoSession::MakeCryptoSession(metrics)), cert_type_(kCertificateWidevine), service_certificate_(new ServiceCertificate()) {} ~CertificateProvisioning() {} @@ -53,7 +53,7 @@ class CertificateProvisioning { video_widevine::SignedProvisioningMessage::ProtocolVersion GetProtocolVersion(); - CryptoSession crypto_session_; + scoped_ptr crypto_session_; CdmCertificateType cert_type_; scoped_ptr service_certificate_; diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 4127581a..ed46c1c3 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -34,6 +34,8 @@ void GenerateEncryptContext(const std::string& input_context, size_t GetOffset(std::string message, std::string field); OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode); +class CryptoSessionFactory; + class CryptoSession { public: typedef OEMCrypto_HDCP_Capability HdcpCapability; @@ -52,7 +54,9 @@ class CryptoSession { // Creates an instance of CryptoSession with the given |crypto_metrics|. // |crypto_metrics| is owned by the caller, must NOT be null, and must // exist as long as the new CryptoSession exists. - explicit CryptoSession(metrics::CryptoMetrics* crypto_metrics); + static CryptoSession* MakeCryptoSession( + metrics::CryptoMetrics* crypto_metrics); + virtual ~CryptoSession(); virtual bool GetProvisioningToken(std::string* client_token); @@ -203,8 +207,26 @@ class CryptoSession { SecurityLevel requested_security_level, CdmClientTokenType* token_type); + protected: + // Creates an instance of CryptoSession with the given |crypto_metrics|. + // |crypto_metrics| is owned by the caller, must NOT be null, and must + // exist as long as the new CryptoSession exists. + explicit CryptoSession(metrics::CryptoMetrics* crypto_metrics); + + int session_count() { return session_count_; } + private: friend class CryptoSessionForTest; + friend class CryptoSessionFactory; + friend class WvCdmTestBase; + + // The global factory method can be set to generate special crypto sessions + // just for testing. These sessions will avoid nonce floods and will ask + // OEMCrypto to use a test keybox. + // Ownership of the object is transfered to CryptoSession. + static void SetCryptoSessionFactory(CryptoSessionFactory* factory) { + factory_.reset(factory); + } void Init(); void Terminate(); @@ -291,9 +313,25 @@ class CryptoSession { CdmCipherMode cipher_mode_; uint32_t api_version_; + static scoped_ptr factory_; + CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSession); }; +class CryptoSessionFactory { + public: + virtual ~CryptoSessionFactory() {} + virtual CryptoSession* MakeCryptoSession( + metrics::CryptoMetrics* crypto_metrics); + + protected: + friend class CryptoSession; + CryptoSessionFactory() {} + + private: + CORE_DISALLOW_COPY_AND_ASSIGN(CryptoSessionFactory); +}; + } // namespace wvcdm #endif // WVCDM_CORE_CRYPTO_SESSION_H_ diff --git a/libwvdrmengine/cdm/core/include/service_certificate.h b/libwvdrmengine/cdm/core/include/service_certificate.h index 1b4de7f1..a76c95f8 100644 --- a/libwvdrmengine/cdm/core/include/service_certificate.h +++ b/libwvdrmengine/cdm/core/include/service_certificate.h @@ -18,6 +18,7 @@ #include "disallow_copy_and_assign.h" #include "license_protocol.pb.h" #include "privacy_crypto.h" +#include "scoped_ptr.h" #include "wv_cdm_types.h" namespace wvcdm { @@ -78,7 +79,7 @@ class ServiceCertificate { std::string provider_id_; // Public key. - std::auto_ptr public_key_; + scoped_ptr public_key_; CORE_DISALLOW_COPY_AND_ASSIGN(ServiceCertificate); }; diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 257550f6..ecc16d0d 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -492,10 +492,11 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, const std::string& query_token, std::string* query_response) { LOGI("CdmEngine::QueryStatus"); - CryptoSession crypto_session(metrics_.GetCryptoMetrics()); + scoped_ptr crypto_session( + CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics())); CdmResponseType status; M_TIME( - status = crypto_session.Open( + status = crypto_session->Open( security_level), metrics_.GetCryptoMetrics(), crypto_session_open_, @@ -511,7 +512,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, if (query_token == QUERY_KEY_SECURITY_LEVEL) { CdmSecurityLevel found_security_level = - crypto_session.GetSecurityLevel(); + crypto_session->GetSecurityLevel(); switch (found_security_level) { case kSecurityLevelL1: *query_response = QUERY_VALUE_SECURITY_LEVEL_L1; @@ -533,7 +534,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, } } else if (query_token == QUERY_KEY_DEVICE_ID) { std::string deviceId; - bool got_id = crypto_session.GetExternalDeviceUniqueId(&deviceId); + bool got_id = crypto_session->GetExternalDeviceUniqueId(&deviceId); metrics_.GetCryptoMetrics()->crypto_session_get_device_unique_id_ .Increment(got_id); if (!got_id) { @@ -544,7 +545,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = deviceId; } else if (query_token == QUERY_KEY_SYSTEM_ID) { uint32_t system_id; - bool got_id = crypto_session.GetSystemId(&system_id); + bool got_id = crypto_session->GetSystemId(&system_id); if (!got_id) { LOGW("CdmEngine::QueryStatus: QUERY_KEY_SYSTEM_ID unknown failure"); return UNKNOWN_ERROR; @@ -555,7 +556,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = system_id_stream.str(); } else if (query_token == QUERY_KEY_PROVISIONING_ID) { std::string provisioning_id; - if (!crypto_session.GetProvisioningId(&provisioning_id)) { + if (!crypto_session->GetProvisioningId(&provisioning_id)) { LOGW("CdmEngine::QueryStatus: GetProvisioningId failed"); return UNKNOWN_ERROR; } @@ -565,7 +566,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, query_token == QUERY_KEY_MAX_HDCP_LEVEL) { CryptoSession::HdcpCapability current_hdcp; CryptoSession::HdcpCapability max_hdcp; - if (!crypto_session.GetHdcpCapabilities(¤t_hdcp, &max_hdcp)) { + if (!crypto_session->GetHdcpCapabilities(¤t_hdcp, &max_hdcp)) { LOGW("CdmEngine::QueryStatus: GetHdcpCapabilities failed"); return UNKNOWN_ERROR; } @@ -574,7 +575,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, current_hdcp : max_hdcp); } else if (query_token == QUERY_KEY_USAGE_SUPPORT) { bool supports_usage_reporting; - bool got_info = crypto_session.UsageInformationSupport( + bool got_info = crypto_session->UsageInformationSupport( &supports_usage_reporting); if (!got_info) { @@ -590,7 +591,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; } else if (query_token == QUERY_KEY_NUMBER_OF_OPEN_SESSIONS) { size_t number_of_open_sessions; - if (!crypto_session.GetNumberOfOpenSessions(&number_of_open_sessions)) { + if (!crypto_session->GetNumberOfOpenSessions(&number_of_open_sessions)) { LOGW("CdmEngine::QueryStatus: GetNumberOfOpenSessions failed"); return UNKNOWN_ERROR; } @@ -600,7 +601,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = open_sessions_stream.str(); } else if (query_token == QUERY_KEY_MAX_NUMBER_OF_SESSIONS) { size_t maximum_number_of_sessions = 0; - if (!crypto_session.GetMaxNumberOfSessions(&maximum_number_of_sessions)) { + if (!crypto_session->GetMaxNumberOfSessions(&maximum_number_of_sessions)) { LOGW("CdmEngine::QueryStatus: GetMaxNumberOfOpenSessions failed"); return UNKNOWN_ERROR; } @@ -610,7 +611,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = max_sessions_stream.str(); } else if (query_token == QUERY_KEY_OEMCRYPTO_API_VERSION) { uint32_t api_version; - if (!crypto_session.GetApiVersion(&api_version)) { + if (!crypto_session->GetApiVersion(&api_version)) { LOGW("CdmEngine::QueryStatus: GetApiVersion failed"); return UNKNOWN_ERROR; } @@ -620,7 +621,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, *query_response = api_version_stream.str(); } else if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) { uint16_t current_srm_version; - if (!crypto_session.GetSrmVersion(¤t_srm_version)) { + if (!crypto_session->GetSrmVersion(¤t_srm_version)) { LOGW("CdmEngine::QueryStatus: GetCurrentSRMVersion failed"); return UNKNOWN_ERROR; } @@ -629,7 +630,7 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level, current_srm_version_stream << current_srm_version; *query_response = current_srm_version_stream.str(); } else if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) { - bool is_srm_update_supported = crypto_session.IsSrmUpdateSupported(); + bool is_srm_update_supported = crypto_session->IsSrmUpdateSupported(); *query_response = is_srm_update_supported ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; } else if (query_token == QUERY_KEY_WVCDM_VERSION) { @@ -833,10 +834,11 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( if (NULL == cert_provisioning_.get()) { // Certificate provisioning object has been released. Check if a concurrent // provisioning attempt has succeeded before declaring failure. - CryptoSession crypto_session(metrics_.GetCryptoMetrics()); + scoped_ptr crypto_session( + CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics())); CdmResponseType status; M_TIME( - status = crypto_session.Open( + status = crypto_session->Open( cert_provisioning_requested_security_level_), metrics_.GetCryptoMetrics(), crypto_session_open_, @@ -848,7 +850,7 @@ CdmResponseType CdmEngine::HandleProvisioningResponse( "missing and crypto session open failed."); return EMPTY_PROVISIONING_CERTIFICATE_2; } - CdmSecurityLevel security_level = crypto_session.GetSecurityLevel(); + CdmSecurityLevel security_level = crypto_session->GetSecurityLevel(); if (!IsProvisioned(security_level)) { LOGE( "CdmEngine::HandleProvisioningResponse: provisioning object " @@ -888,9 +890,10 @@ bool CdmEngine::IsProvisioned(CdmSecurityLevel security_level) { CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { // Devices with baked-in DRM certs cannot be reprovisioned and therefore must // not be unprovisioned. - CryptoSession crypto_session(metrics_.GetCryptoMetrics()); + scoped_ptr crypto_session( + CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics())); CdmClientTokenType token_type = kClientTokenUninitialized; - CdmResponseType res = crypto_session.GetProvisioningMethod( + CdmResponseType res = crypto_session->GetProvisioningMethod( security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault, &token_type); if (res != NO_ERROR) { @@ -921,10 +924,11 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { } CdmResponseType CdmEngine::DeleteUsageTable(CdmSecurityLevel security_level) { - CryptoSession crypto_session(metrics_.GetCryptoMetrics()); + scoped_ptr crypto_session( + CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics())); CdmResponseType status; M_TIME( - status = crypto_session.Open( + status = crypto_session->Open( security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault), @@ -937,7 +941,7 @@ CdmResponseType CdmEngine::DeleteUsageTable(CdmSecurityLevel security_level) { status); return UNPROVISION_ERROR_4; } - status = crypto_session.DeleteAllUsageReports(); + status = crypto_session->DeleteAllUsageReports(); metrics_.GetCryptoMetrics()->crypto_session_delete_all_usage_reports_ .Increment(status); if (status != NO_ERROR) { @@ -1004,7 +1008,7 @@ CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id, // Got provider token. Remove from OEMCrypto. scoped_ptr crypto_session( - new CryptoSession(metrics_.GetCryptoMetrics())); + CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics())); CdmResponseType status = crypto_session->Open( security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault); if (status == NO_ERROR) { @@ -1213,7 +1217,7 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo( // Got at least one provider token. Remove from OEMCrypto. scoped_ptr crypto_session( - new CryptoSession(metrics_.GetCryptoMetrics())); + CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics())); CdmResponseType status = crypto_session->Open( security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault); if (status == NO_ERROR) { @@ -1367,7 +1371,7 @@ CdmResponseType CdmEngine::RemoveUsageInfo( DeviceFiles::GetUsageInfoFileName(app_id), provider_session_token); scoped_ptr crypto_session( - new CryptoSession(metrics_.GetCryptoMetrics())); + CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics())); status = crypto_session->Open( static_cast(j) == kSecurityLevelL3 ? kLevel3 : kLevelDefault); @@ -1805,7 +1809,7 @@ void CdmEngine::DeleteAllUsageReportsUponFactoryReset() { if (!file_system_->Exists(device_base_path_level1) && !file_system_->Exists(device_base_path_level3)) { scoped_ptr crypto_session( - new CryptoSession(metrics_.GetCryptoMetrics())); + CryptoSession::MakeCryptoSession(metrics_.GetCryptoMetrics())); CdmResponseType status; M_TIME( status = crypto_session->Open( diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index f4105a0c..813ebd8f 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -49,7 +49,7 @@ CdmSession::CdmSession(FileSystem* file_system, mock_policy_engine_in_use_(false) { assert(metrics_); // metrics_ must not be null. crypto_metrics_ = metrics_->GetCryptoMetrics(); - crypto_session_.reset(new CryptoSession(crypto_metrics_)); + crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_)); life_span_.Start(); } @@ -734,7 +734,7 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) { // it, so close and reopen session. CdmResponseType sts; crypto_session_->Close(); - crypto_session_.reset(new CryptoSession(crypto_metrics_)); + crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_)); M_TIME(sts = crypto_session_->Open(requested_security_level_), crypto_metrics_, crypto_session_open_, sts, requested_security_level_); if (sts != NO_ERROR) return sts; @@ -870,7 +870,7 @@ bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) { CdmResponseType CdmSession::RemoveKeys() { CdmResponseType sts; - crypto_session_.reset(new CryptoSession(crypto_metrics_)); + crypto_session_.reset(CryptoSession::MakeCryptoSession(crypto_metrics_)); // Ignore errors M_TIME( sts = crypto_session_->Open(requested_security_level_), diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index 0d3345b6..0a34368f 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -142,7 +142,7 @@ bool CertificateProvisioning::SetSpoidParameter( } else if (origin != EMPTY_ORIGIN) { // Legacy behavior - Concatenate Unique ID with Origin std::string device_unique_id; - if (!crypto_session_.GetInternalDeviceUniqueId(&device_unique_id)) { + if (!crypto_session_->GetInternalDeviceUniqueId(&device_unique_id)) { LOGE("CertificateProvisioning::SetSpoidParameter: Failure getting " "device unique ID"); return false; @@ -158,7 +158,7 @@ bool CertificateProvisioning::SetSpoidParameter( */ SignedProvisioningMessage::ProtocolVersion CertificateProvisioning::GetProtocolVersion() { - if (crypto_session_.GetPreProvisionTokenType() == kClientTokenOemCert) + if (crypto_session_->GetPreProvisionTokenType() == kClientTokenOemCert) return SignedProvisioningMessage::VERSION_3; else return SignedProvisioningMessage::VERSION_2; @@ -183,7 +183,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( default_url->assign(kProvisioningServerUrl); - CdmResponseType status = crypto_session_.Open(requested_security_level); + CdmResponseType status = crypto_session_->Open(requested_security_level); if (NO_ERROR != status) { LOGE("GetProvisioningRequest: fails to create a crypto session"); return status; @@ -193,7 +193,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( ProvisioningRequest provisioning_request; wvcdm::ClientIdentification id; - status = id.Init(&crypto_session_); + status = id.Init(crypto_session_.get()); if (status != NO_ERROR) return status; video_widevine::ClientIdentification* client_id = @@ -212,12 +212,12 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( // Encrypt client identification EncryptedClientIdentification* encrypted_client_id = provisioning_request.mutable_encrypted_client_id(); - status = service_certificate_->EncryptClientId(&crypto_session_, client_id, - encrypted_client_id); + status = service_certificate_->EncryptClientId( + crypto_session_.get(), client_id, encrypted_client_id); provisioning_request.clear_client_id(); uint32_t nonce; - if (!crypto_session_.GenerateNonce(&nonce)) { + if (!crypto_session_->GenerateNonce(&nonce)) { LOGE("GetProvisioningRequest: fails to generate a nonce"); return CERT_PROVISIONING_NONCE_GENERATION_ERROR; } @@ -254,7 +254,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( // Derives signing and encryption keys and constructs signature. std::string request_signature; - if (!crypto_session_.PrepareRequest(serialized_message, true, + if (!crypto_session_->PrepareRequest(serialized_message, true, &request_signature)) { LOGE("GetProvisioningRequest: fails to prepare request"); return CERT_PROVISIONING_REQUEST_ERROR_3; @@ -351,7 +351,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( // If Provisioning 3.0 (OEM Cert provisioned), verify that the // message is properly signed. - if (crypto_session_.GetPreProvisionTokenType() == kClientTokenOemCert) { + if (crypto_session_->GetPreProvisionTokenType() == kClientTokenOemCert) { if (service_certificate_->VerifySignedMessage(signed_message, signature) != NO_ERROR) { // TODO(b/69562876): if the cert is bad, request a new one. @@ -369,14 +369,14 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( std::string wrapped_private_key; - if (!crypto_session_.RewrapCertificate(signed_message, signature, nonce, + if (!crypto_session_->RewrapCertificate(signed_message, signature, nonce, new_private_key, iv, wrapping_key, &wrapped_private_key)) { LOGE("HandleProvisioningResponse: RewrapCertificate fails"); return CERT_PROVISIONING_RESPONSE_ERROR_6; } - crypto_session_.Close(); + crypto_session_->Close(); if (cert_type_ == kCertificateX509) { *cert = provisioning_response.device_certificate(); @@ -391,7 +391,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse( provisioning_response.device_certificate(); DeviceFiles handle(file_system); - if (!handle.Init(crypto_session_.GetSecurityLevel())) { + if (!handle.Init(crypto_session_->GetSecurityLevel())) { LOGE("HandleProvisioningResponse: failed to init DeviceFiles"); return CERT_PROVISIONING_RESPONSE_ERROR_7; } diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 8b3351e6..3451527b 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -2574,4 +2574,20 @@ void CryptoSession::IncrementIV(uint64_t increase_by, (*counter_buffer) = htonll64(ntohll64(*counter_buffer) + increase_by); } +// The factory will either be set by WvCdmTestBase, or a default factory is +// created on the first call to MakeCryptoSession. +scoped_ptr CryptoSession::factory_(NULL); + +CryptoSession* CryptoSession::MakeCryptoSession( + metrics::CryptoMetrics* crypto_metrics) { + // If the factory_ has not been set, then use a default factory. + if (factory_.get() == NULL) factory_.reset(new CryptoSessionFactory()); + return factory_->MakeCryptoSession(crypto_metrics); +} + +CryptoSession* CryptoSessionFactory::MakeCryptoSession( + metrics::CryptoMetrics* crypto_metrics) { + return new CryptoSession(crypto_metrics); +} + } // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/src/license.cpp b/libwvdrmengine/cdm/core/src/license.cpp index 2f7fbd49..918b3baa 100644 --- a/libwvdrmengine/cdm/core/src/license.cpp +++ b/libwvdrmengine/cdm/core/src/license.cpp @@ -143,6 +143,7 @@ static std::vector ExtractContentKeys(const License& license) { key.set_key_id(license.key(i).id()); // Strip off PKCS#5 padding - since we know the key is 16 or 32 bytes, // the padding will always be 16 bytes. + // TODO(b/111069024): remove this! if (license.key(i).key().size() > 16) { length = license.key(i).key().size() - 16; } else { diff --git a/libwvdrmengine/cdm/core/src/usage_table_header.cpp b/libwvdrmengine/cdm/core/src/usage_table_header.cpp index a88db8f6..cb463ed0 100644 --- a/libwvdrmengine/cdm/core/src/usage_table_header.cpp +++ b/libwvdrmengine/cdm/core/src/usage_table_header.cpp @@ -285,7 +285,7 @@ CdmResponseType UsageTableHeader::MoveEntry( scoped_ptr scoped_crypto_session; CryptoSession* crypto_session = test_crypto_session_.get(); if (crypto_session == NULL) { - scoped_crypto_session.reset((new CryptoSession(metrics))); + scoped_crypto_session.reset((CryptoSession::MakeCryptoSession(metrics))); crypto_session = scoped_crypto_session.get(); } @@ -479,7 +479,7 @@ CdmResponseType UsageTableHeader::Shrink( scoped_ptr scoped_crypto_session; CryptoSession* crypto_session = test_crypto_session_.get(); if (crypto_session == NULL) { - scoped_crypto_session.reset((new CryptoSession(metrics))); + scoped_crypto_session.reset((CryptoSession::MakeCryptoSession(metrics))); crypto_session = scoped_crypto_session.get(); } @@ -549,32 +549,33 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable( if (provider_session_token.empty()) continue; - CryptoSession crypto_session(metrics); - CdmResponseType status = crypto_session.Open(requested_security_level_); + scoped_ptr crypto_session( + CryptoSession::MakeCryptoSession(metrics)); + CdmResponseType status = crypto_session->Open(requested_security_level_); if (status != NO_ERROR) continue; // We create this entry since OEMCrypto_CopyOldUsageEntry needs the old // usage table to be loaded in order to copy an entry. - if (!CreateDummyOldUsageEntry(&crypto_session)) continue; + if (!CreateDummyOldUsageEntry(crypto_session.get())) continue; - status = AddEntry(&crypto_session, true /* persistent license */, + status = AddEntry(crypto_session.get(), true /* persistent license */, key_set_ids[i], kEmptyString, &usage_entry_number); if (status != NO_ERROR) continue; - status = crypto_session.CopyOldUsageEntry(provider_session_token); + status = crypto_session->CopyOldUsageEntry(provider_session_token); if (status != NO_ERROR) { - crypto_session.Close(); + crypto_session->Close(); Shrink(metrics, 1); continue; } - status = UpdateEntry(&crypto_session, &usage_entry); + status = UpdateEntry(crypto_session.get(), &usage_entry); if (status != NO_ERROR) { - crypto_session.Close(); + crypto_session->Close(); Shrink(metrics, 1); continue; } @@ -631,36 +632,37 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable( continue; } - CryptoSession crypto_session(metrics); - CdmResponseType status = crypto_session.Open(requested_security_level_); + scoped_ptr crypto_session( + CryptoSession::MakeCryptoSession(metrics)); + CdmResponseType status = crypto_session->Open(requested_security_level_); if (status != NO_ERROR) continue; // We create this entry since OEMCrypto_CopyOldUsageEntry needs the old // usage table to be loaded in order to copy an entry. - if (!CreateDummyOldUsageEntry(&crypto_session)) continue; + if (!CreateDummyOldUsageEntry(crypto_session.get())) continue; // TODO(rfrias): We need to fill in the app id, but it is hashed // and we have no way to extract. Use the hased filename instead? - status = AddEntry(&crypto_session, false /* usage info */, + status = AddEntry(crypto_session.get(), false /* usage info */, usage_data[j].key_set_id, usage_info_file_names[i], &(usage_data[j].usage_entry_number)); if (status != NO_ERROR) continue; - status = crypto_session.CopyOldUsageEntry( + status = crypto_session->CopyOldUsageEntry( usage_data[j].provider_session_token); if (status != NO_ERROR) { - crypto_session.Close(); + crypto_session->Close(); Shrink(metrics, 1); continue; } - status = UpdateEntry(&crypto_session, &(usage_data[j].usage_entry)); + status = UpdateEntry(crypto_session.get(), &(usage_data[j].usage_entry)); if (status != NO_ERROR) { - crypto_session.Close(); + crypto_session->Close(); Shrink(metrics, 1); continue; } diff --git a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp index 06b6200c..efb31bbf 100644 --- a/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_engine_test.cpp @@ -23,6 +23,7 @@ #include "properties.h" #include "scoped_ptr.h" #include "string_conversions.h" +#include "test_base.h" #include "test_printers.h" #include "url_request.h" #include "wv_cdm_constants.h" @@ -116,7 +117,7 @@ bool ExtractSignedMessage(const std::string& response, } // namespace -class WvCdmEnginePreProvTest : public testing::Test { +class WvCdmEnginePreProvTest : public WvCdmTestBase { public: WvCdmEnginePreProvTest() : cdm_engine_(&file_system_), session_opened_(false) {} @@ -124,6 +125,7 @@ class WvCdmEnginePreProvTest : public testing::Test { virtual ~WvCdmEnginePreProvTest() {} virtual void SetUp() { + WvCdmTestBase::SetUp(); session_opened_ = false; } @@ -188,9 +190,6 @@ class WvCdmEnginePreProvTest : public testing::Test { CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority; std::string cert, wrapped_key; - // Keep a crypto session alive so that OEMCrypto won't terminate while we - // try to provision. This is needed for testing nonce floods. - CryptoSession keep_alive(cdm_engine_.GetMetrics()->GetCryptoMetrics()); CdmResponseType result = NO_ERROR; for(int i = 0; i < 2; ++i) { // Retry once if there is a nonce problem. @@ -372,19 +371,9 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest { CdmKeyRequest key_request; - CdmResponseType result = NO_ERROR; - for(int i=0; i < 2; i++) { // Retry once if there is a nonce problem. - result = cdm_engine_.GenerateKeyRequest( - session_id_, key_set_id, init_data, - kLicenseTypeStreaming, app_parameters, - &key_request); - if (result == LICENSE_REQUEST_NONCE_GENERATION_ERROR) { - LOGW("Woops. Nonce problem. Try again?"); - sleep(1); - } else { - break; - } - } + CdmResponseType result = cdm_engine_.GenerateKeyRequest( + session_id_, key_set_id, init_data, kLicenseTypeStreaming, + app_parameters, &key_request); EXPECT_EQ(KEY_MESSAGE, result); key_msg_ = key_request.message; @@ -393,16 +382,8 @@ class WvCdmEngineTest : public WvCdmEnginePreProvTest { void GenerateRenewalRequest() { CdmKeyRequest request; - CdmResponseType result = NO_ERROR; - for (int i = 0; i < 2; i++) { // Retry once if there is a nonce problem. - result = cdm_engine_.GenerateRenewalRequest(session_id_, &request); - if (result == LICENSE_RENEWAL_NONCE_GENERATION_ERROR) { - LOGW("Woops. Nonce problem. Try again?"); - sleep(1); - } else { - break; - } - } + CdmResponseType result = + cdm_engine_.GenerateRenewalRequest(session_id_, &request); EXPECT_EQ(KEY_MESSAGE, result); key_msg_ = request.message; diff --git a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp index 04f215e3..dc62ce21 100644 --- a/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/cdm_session_unittest.cpp @@ -11,6 +11,7 @@ #include "scoped_ptr.h" #include "service_certificate.h" #include "string_conversions.h" +#include "test_base.h" #include "test_printers.h" #include "usage_table_header.h" #include "wv_cdm_constants.h" @@ -122,10 +123,10 @@ class MockUsageTableHeader : public UsageTableHeader { CdmUsageEntry* usage_entry)); }; -class MockCryptoSession : public CryptoSession { +class MockCryptoSession : public TestCryptoSession { public: MockCryptoSession(metrics::CryptoMetrics* crypto_metrics) - : CryptoSession(crypto_metrics) { + : TestCryptoSession(crypto_metrics) { // By default, call the concrete implementation of GetUsageSupportType. ON_CALL(*this, GetUsageSupportType(_)) .WillByDefault( @@ -167,9 +168,10 @@ class MockCdmLicense : public CdmLicense { } // namespace -class CdmSessionTest : public ::testing::Test { +class CdmSessionTest : public WvCdmTestBase { protected: virtual void SetUp() { + WvCdmTestBase::SetUp(); cdm_session_.reset(new CdmSession(NULL, &metrics_)); // Inject testing mocks. license_parser_ = new MockCdmLicense(cdm_session_->session_id()); diff --git a/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp b/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp index 6c1575ff..8666259c 100644 --- a/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/crypto_session_unittest.cpp @@ -15,6 +15,8 @@ #include "metrics.pb.h" #include "metrics_collections.h" #include "scoped_ptr.h" +#include "test_base.h" +#include "test_printers.h" #include "wv_cdm_types.h" namespace { @@ -240,10 +242,10 @@ const uint32_t kOemCertSystemId = 7346; namespace wvcdm { -class CryptoSessionForTest : public CryptoSession, public testing::Test { +class CryptoSessionForTest : public TestCryptoSession, public WvCdmTestBase { public: using CryptoSession::ExtractSystemIdFromOemCert; - CryptoSessionForTest() : CryptoSession(metrics_.GetCryptoMetrics()) {} + CryptoSessionForTest() : TestCryptoSession(metrics_.GetCryptoMetrics()) {} void SetUp() {} @@ -264,7 +266,7 @@ TEST(CryptoSessionTest, CanExtractSystemIdFromOemCertificate) { ASSERT_EQ(kOemCertSystemId, system_id); } -class CryptoSessionMetricsTest : public testing::Test { +class CryptoSessionMetricsTest : public WvCdmTestBase { protected: uint32_t FindKeyboxSystemID() { OEMCryptoResult sts; @@ -280,11 +282,12 @@ class CryptoSessionMetricsTest : public testing::Test { TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) { metrics::CryptoMetrics crypto_metrics; - CryptoSession session(&crypto_metrics); - session.Open(wvcdm::kLevelDefault); + scoped_ptr session( + CryptoSession::MakeCryptoSession(&crypto_metrics)); + session->Open(wvcdm::kLevelDefault); // Exercise a method that will touch a metric. CdmUsageSupportType usage_type; - ASSERT_EQ(NO_ERROR, session.GetUsageSupportType(&usage_type)); + ASSERT_EQ(NO_ERROR, session->GetUsageSupportType(&usage_type)); drm_metrics::WvCdmMetrics::CryptoMetrics metrics_proto; crypto_metrics.Serialize(&metrics_proto); @@ -305,7 +308,7 @@ TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) { metrics_proto.oemcrypto_usage_table_support().int_value()); // Validate metrics that differ based on provisioning type. - CdmClientTokenType token_type = session.GetPreProvisionTokenType(); + CdmClientTokenType token_type = session->GetPreProvisionTokenType(); if (token_type == kClientTokenKeybox) { uint32_t system_id = FindKeyboxSystemID(); @@ -337,18 +340,19 @@ TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) { TEST_F(CryptoSessionMetricsTest, GetProvisioningTokenValidMetrics) { metrics::CryptoMetrics crypto_metrics; - CryptoSession session(&crypto_metrics); + scoped_ptr session( + CryptoSession::MakeCryptoSession(&crypto_metrics)); - ASSERT_EQ(NO_ERROR, session.Open(wvcdm::kLevelDefault)); + ASSERT_EQ(NO_ERROR, session->Open(wvcdm::kLevelDefault)); - CdmClientTokenType token_type = session.GetPreProvisionTokenType(); + CdmClientTokenType token_type = session->GetPreProvisionTokenType(); LOGI("token_type: %d", token_type); // DRM Certificate provisioning method does not support a provisioning // token. Otherwise, we should be able to fetch the token. std::string token; if (token_type != kClientTokenDrmCert) { - ASSERT_TRUE(session.GetProvisioningToken(&token)); + ASSERT_TRUE(session->GetProvisioningToken(&token)); } drm_metrics::WvCdmMetrics::CryptoMetrics metrics_proto; diff --git a/libwvdrmengine/cdm/core/test/license_unittest.cpp b/libwvdrmengine/cdm/core/test/license_unittest.cpp index 9c13fdb2..311943de 100644 --- a/libwvdrmengine/cdm/core/test/license_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/license_unittest.cpp @@ -15,6 +15,8 @@ #include "properties.h" #include "service_certificate.h" #include "string_conversions.h" +#include "test_base.h" +#include "test_printers.h" #include "wv_cdm_constants.h" namespace wvcdm { @@ -142,10 +144,10 @@ const CryptoSession::SupportedCertificateTypes kDefaultSupportedCertTypes = { true }; -class MockCryptoSession : public CryptoSession { +class MockCryptoSession : public TestCryptoSession { public: MockCryptoSession(metrics::CryptoMetrics* crypto_metrics) - : CryptoSession(crypto_metrics) { } + : TestCryptoSession(crypto_metrics) { } MOCK_METHOD0(IsOpen, bool()); MOCK_METHOD1(GenerateRequestId, bool(std::string*)); MOCK_METHOD1(UsageInformationSupport, bool(bool*)); @@ -194,11 +196,12 @@ using ::testing::Return; using ::testing::SetArgPointee; using ::testing::UnorderedElementsAre; -class CdmLicenseTest : public ::testing::Test { +class CdmLicenseTest : public WvCdmTestBase { protected: CdmLicenseTest(const std::string& pssh = (kCencInitDataHdr + kCencPssh)) : pssh_(pssh) {} virtual void SetUp() { + WvCdmTestBase::SetUp(); clock_ = new MockClock(); crypto_session_ = new MockCryptoSession(&crypto_metrics_); init_data_ = new MockInitializationData(CENC_INIT_DATA_FORMAT, pssh_); diff --git a/libwvdrmengine/cdm/core/test/policy_engine_constraints_unittest.cpp b/libwvdrmengine/cdm/core/test/policy_engine_constraints_unittest.cpp index eebb6f92..b1eb7719 100644 --- a/libwvdrmengine/cdm/core/test/policy_engine_constraints_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/policy_engine_constraints_unittest.cpp @@ -11,6 +11,8 @@ #include "policy_engine.h" #include "mock_clock.h" #include "scoped_ptr.h" +#include "test_base.h" +#include "test_printers.h" #include "wv_cdm_event_listener.h" #include "wv_cdm_types.h" @@ -62,10 +64,10 @@ const OutputProtection::HDCP kHdcpV2_1 = OutputProtection::HDCP_V2_1; // should match kHdcpCheckInterval in policy_engine.cpp const int64_t kHdcpInterval = 10; -class HdcpOnlyMockCryptoSession : public CryptoSession { +class HdcpOnlyMockCryptoSession : public TestCryptoSession { public: HdcpOnlyMockCryptoSession(metrics::CryptoMetrics* crypto_metrics) - : CryptoSession(crypto_metrics) { } + : TestCryptoSession(crypto_metrics) { } MOCK_METHOD2(GetHdcpCapabilities, bool(HdcpCapability*, HdcpCapability*)); }; @@ -82,7 +84,7 @@ class MockCdmEventListener : public WvCdmEventListener { } // namespace -class PolicyEngineConstraintsTest : public Test { +class PolicyEngineConstraintsTest : public WvCdmTestBase { public: PolicyEngineConstraintsTest() : crypto_session_(&dummy_metrics_) { @@ -90,6 +92,7 @@ class PolicyEngineConstraintsTest : public Test { protected: virtual void SetUp() { + WvCdmTestBase::SetUp(); current_time_ = 0; policy_engine_.reset(new PolicyEngine(kSessionId, &mock_event_listener_, diff --git a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp index 81968152..eeb609ff 100644 --- a/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/policy_engine_unittest.cpp @@ -14,6 +14,7 @@ #include "mock_clock.h" #include "policy_engine.h" #include "scoped_ptr.h" +#include "test_base.h" #include "test_printers.h" #include "wv_cdm_event_listener.h" #include "wv_cdm_constants.h" @@ -57,10 +58,10 @@ int64_t ParseInt(const std::string& str) { return ret; } -class HdcpOnlyMockCryptoSession : public CryptoSession { +class HdcpOnlyMockCryptoSession : public TestCryptoSession { public: HdcpOnlyMockCryptoSession(metrics::CryptoMetrics* metrics) : - CryptoSession(metrics) {} + TestCryptoSession(metrics) {} MOCK_METHOD2(GetHdcpCapabilities, bool(HdcpCapability*, HdcpCapability*)); bool DoRealGetHdcpCapabilities(HdcpCapability* current, @@ -99,12 +100,13 @@ using ::testing::Return; using ::testing::StrictMock; using ::testing::UnorderedElementsAre; -class PolicyEngineTest : public ::testing::Test { +class PolicyEngineTest : public WvCdmTestBase { public: PolicyEngineTest() : crypto_session_(&dummy_metrics_) { } protected: virtual void SetUp() { + WvCdmTestBase::SetUp(); policy_engine_.reset( new PolicyEngine(kSessionId, &mock_event_listener_, &crypto_session_)); diff --git a/libwvdrmengine/cdm/core/test/test_base.cpp b/libwvdrmengine/cdm/core/test/test_base.cpp new file mode 100644 index 00000000..ce0aa2f0 --- /dev/null +++ b/libwvdrmengine/cdm/core/test/test_base.cpp @@ -0,0 +1,82 @@ +// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine Master +// License Agreement. +// This file adds some print methods so that when unit tests fail, the +// will print the name of an enumeration instead of the numeric value. + +#include "test_base.h" + +#include + +#include +#include +#include +#include + +#include "cdm_engine.h" +#include "crypto_session.h" +#include "file_store.h" +#include "log.h" +#include "oec_device_features.h" +#include "oec_test_data.h" +#include "properties.h" +#include "test_printers.h" +#include "url_request.h" + +namespace wvcdm { + +TestCryptoSession::TestCryptoSession(metrics::CryptoMetrics* crypto_metrics) + : CryptoSession(crypto_metrics) { + // The first CryptoSession should have initialized OEMCrypto. This is right + // after that, so should tell oemcrypto to use a test keybox. + if (session_count() == 1) { + WvCdmTestBase::InstallTestRootOfTrust(); + } +} + +bool TestCryptoSession::GenerateNonce(uint32_t* nonce) { + for (int i = 0; !CryptoSession::GenerateNonce(nonce); i++) { + LOGV("Recovering from nonce flood."); + if (i > 2) return false; + sleep(1); + } + return true; +} + +class TestCryptoSessionFactory : public CryptoSessionFactory { + CryptoSession* MakeCryptoSession(metrics::CryptoMetrics* crypto_metrics) { + return new TestCryptoSession(crypto_metrics); + } +}; + +void WvCdmTestBase::SetUp() { + ::testing::Test::SetUp(); + Properties::Init(); + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + LOGD("Running test %s.%s", test_info->test_case_name(), test_info->name()); + CryptoSession::SetCryptoSessionFactory(new TestCryptoSessionFactory()); + // TODO(fredgc): Add a test version of DeviceFiles. +} + +void WvCdmTestBase::InstallTestRootOfTrust() { + switch (wvoec::global_features.derive_key_method) { + case wvoec::DeviceFeatures::LOAD_TEST_KEYBOX: + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_LoadTestKeybox( + reinterpret_cast(&wvoec::kTestKeybox), + sizeof(wvoec::kTestKeybox))); + break; + case wvoec::DeviceFeatures::LOAD_TEST_RSA_KEY: + // Rare case: used by devices with baked in DRM cert. + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_LoadTestRSAKey()); + break; + case wvoec::DeviceFeatures::TEST_PROVISION_30: + // Can use oem certificate to install test rsa key. + break; + default: + FAIL() << "Cannot run test without test keybox or RSA key installed."; + } +} + +} // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/test/test_base.h b/libwvdrmengine/cdm/core/test/test_base.h new file mode 100644 index 00000000..bf2be99d --- /dev/null +++ b/libwvdrmengine/cdm/core/test/test_base.h @@ -0,0 +1,37 @@ +// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary +// source code may only be used and distributed under the Widevine Master +// License Agreement. + +#ifndef WVCDM_CORE_TEST_BASE_H_ +#define WVCDM_CORE_TEST_BASE_H_ + +#include + +#include "config_test_env.h" +#include "crypto_session.h" +#include "metrics_collections.h" + +namespace wvcdm { +// This is the base class for Widevine CDM integration tests. It's main use is +// to configure OEMCrypto to use a test keybox. +class WvCdmTestBase : public ::testing::Test { + public: + WvCdmTestBase() {} + virtual ~WvCdmTestBase() {} + virtual void SetUp(); + + // Install a test keybox, if appropriate. + static void InstallTestRootOfTrust(); +}; + +class TestCryptoSession : public CryptoSession { + public: + explicit TestCryptoSession(metrics::CryptoMetrics* crypto_metrics); + // This intercepts nonce flood errors, which is useful for tests that request + // many nonces and are not time critical. + bool GenerateNonce(uint32_t* nonce); +}; + +} // namespace wvcdm + +#endif // WVCDM_CORE_TEST_BASE_H_ diff --git a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp index ddd963fa..621f24dd 100644 --- a/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp +++ b/libwvdrmengine/cdm/core/test/usage_table_header_unittest.cpp @@ -11,6 +11,8 @@ #include "crypto_session.h" #include "device_files.h" #include "file_store.h" +#include "test_base.h" +#include "test_printers.h" #include "wv_cdm_constants.h" #include "wv_cdm_types.h" @@ -225,10 +227,10 @@ class MockDeviceFiles : public DeviceFiles { FileSystem file_system_; }; -class MockCryptoSession : public CryptoSession { +class MockCryptoSession : public TestCryptoSession { public: MockCryptoSession(metrics::CryptoMetrics* metrics) - : CryptoSession(metrics) {} + : TestCryptoSession(metrics) {} MOCK_METHOD1(Open, CdmResponseType(SecurityLevel)); MOCK_METHOD1(LoadUsageTableHeader, CdmResponseType(const CdmUsageTableHeader&)); @@ -255,7 +257,7 @@ using ::testing::StrEq; using ::testing::UnorderedElementsAre; using ::testing::UnorderedElementsAreArray; -class UsageTableHeaderTest : public ::testing::Test { +class UsageTableHeaderTest : public WvCdmTestBase { public: static void SetUpTestCase() { InitVectorConstants(); @@ -263,6 +265,7 @@ class UsageTableHeaderTest : public ::testing::Test { protected: virtual void SetUp() { + WvCdmTestBase::SetUp(); // UsageTableHeader will take ownership of the pointer device_files_ = new MockDeviceFiles(); crypto_session_ = new MockCryptoSession(&crypto_metrics_); diff --git a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp index 286cd7dc..96b974a4 100644 --- a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp @@ -188,6 +188,14 @@ bool StringToInt64(const std::string& input, int64_t* output) { } // namespace +// GTest requires PrintTo to be in the same namespace as the thing it prints, +// which is std::vector in this case. +namespace std { +void PrintTo(const vector& value, ostream* os) { + *os << wvcdm::b2a_hex(value); +} +} // namespace std + using ::testing::Contains; using ::testing::Pair; using ::testing::StrNe; diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 9cc57d6c..a8094967 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -48,8 +48,6 @@ namespace { // HTTP response codes. const int kHttpOk = 200; -const int kHttpBadRequest = 400; -const int kHttpInternalServerError = 500; const wvcdm::CdmIdentifier kExampleIdentifier = { wvcdm::EMPTY_SPOID, diff --git a/libwvdrmengine/cdm/test/test_base.h b/libwvdrmengine/cdm/test/test_base.h deleted file mode 100644 index d5c3216b..00000000 --- a/libwvdrmengine/cdm/test/test_base.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary -// source code may only be used and distributed under the Widevine Master -// License Agreement. - -#include - -namespace wvcdm { -class WvCdmTestBase : public ::testing::Test { - public: - WvCdmTestBase() {} - virtual ~WvCdmTestBase() {} - - protected: - virtual void SetUp() { - const ::testing::TestInfo* const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - LOGD("Running test %s.%s", test_info->test_case_name(), - test_info->name()); - } -}; -} // namespace wvcdm diff --git a/libwvdrmengine/cdm/test/unit-test.mk b/libwvdrmengine/cdm/test/unit-test.mk index 6ece55c7..6f759ae5 100644 --- a/libwvdrmengine/cdm/test/unit-test.mk +++ b/libwvdrmengine/cdm/test/unit-test.mk @@ -11,9 +11,11 @@ LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES := \ $(test_src_dir)/$(test_name).cpp \ + ../../oemcrypto/test/oec_device_features.cpp \ ../core/test/config_test_env.cpp \ ../core/test/http_socket.cpp \ ../core/test/license_request.cpp \ + ../core/test/test_base.cpp \ ../core/test/test_printers.cpp \ ../core/test/url_request.cpp @@ -25,6 +27,7 @@ LOCAL_C_INCLUDES := \ vendor/widevine/libwvdrmengine/cdm/metrics/include \ vendor/widevine/libwvdrmengine/cdm/util/include \ vendor/widevine/libwvdrmengine/oemcrypto/include \ + vendor/widevine/libwvdrmengine/oemcrypto/test \ LOCAL_C_INCLUDES += external/protobuf/src diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index e3e5dd0c..8d66df2f 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -37,10 +37,6 @@ #include "oemcrypto_types.h" #include "string_conversions.h" -#ifdef CDM_TESTS -#include "properties.h" -#endif - using ::testing::Bool; using ::testing::Combine; using ::testing::Range; @@ -77,9 +73,6 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil { virtual void SetUp() { ::testing::Test::SetUp(); -#ifdef CDM_TESTS - wvcdm::Properties::Init(); -#endif wvcdm::g_cutoff = wvcdm::LOG_INFO; const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test_main.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test_main.cpp index 1dabae30..f53d7edd 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test_main.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test_main.cpp @@ -4,9 +4,6 @@ #include "OEMCryptoCENC.h" #include "log.h" #include "oec_device_features.h" -#ifdef CDM_TESTS -#include "properties.h" -#endif static void acknowledge_cast() { std::cout @@ -17,9 +14,6 @@ static void acknowledge_cast() { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); -#ifdef CDM_TESTS - wvcdm::Properties::Init(); -#endif wvcdm::g_cutoff = wvcdm::LOG_INFO; bool is_cast_receiver = false; bool force_load_test_keybox = false;