diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index 453374cf..6f9dad11 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -13,6 +13,7 @@ #include "lock.h" #include "oemcrypto_adapter.h" #include "scoped_ptr.h" +#include "wv_cdm_constants.h" #include "wv_cdm_types.h" namespace wvcdm { @@ -31,7 +32,7 @@ typedef std::map< class CdmEngine { public: - CdmEngine(FileSystem* file_system); + CdmEngine(FileSystem* file_system, const std::string& spoid = EMPTY_SPOID); virtual ~CdmEngine(); // Session related methods @@ -236,6 +237,7 @@ class CdmEngine { SecurityLevel cert_provisioning_requested_security_level_; FileSystem* file_system_; Clock clock_; + std::string spoid_; static bool seeded_; diff --git a/libwvdrmengine/cdm/core/include/certificate_provisioning.h b/libwvdrmengine/cdm/core/include/certificate_provisioning.h index 6205b869..fd9a9dac 100644 --- a/libwvdrmengine/cdm/core/include/certificate_provisioning.h +++ b/libwvdrmengine/cdm/core/include/certificate_provisioning.h @@ -27,6 +27,7 @@ class CertificateProvisioning { CdmCertificateType cert_type, const std::string& cert_authority, const std::string& origin, + const std::string& spoid, CdmProvisioningRequest* request, std::string* default_url); CdmResponseType HandleProvisioningResponse( @@ -39,6 +40,9 @@ class CertificateProvisioning { bool GetProvisioningTokenType( video_widevine::ClientIdentification::TokenType* token_type); + bool FillStableIdField(const std::string& origin, const std::string& spoid, + video_widevine::ProvisioningRequest* request); + video_widevine::SignedProvisioningMessage::ProtocolVersion GetProtocolVersion(); diff --git a/libwvdrmengine/cdm/core/include/file_store.h b/libwvdrmengine/cdm/core/include/file_store.h index 6e28990f..5b207ce3 100644 --- a/libwvdrmengine/cdm/core/include/file_store.h +++ b/libwvdrmengine/cdm/core/include/file_store.h @@ -58,9 +58,14 @@ class FileSystem { const std::string& origin() const { return origin_; } void SetOrigin(const std::string& origin); + const std::string& identifier() const { return identifier_; } + void SetIdentifier(const std::string& identifier); + bool IsGlobal() const { return identifier_.empty(); } + private: Impl* impl_; std::string origin_; + std::string identifier_; CORE_DISALLOW_COPY_AND_ASSIGN(FileSystem); }; diff --git a/libwvdrmengine/cdm/core/include/properties.h b/libwvdrmengine/cdm/core/include/properties.h index 632dfee2..0f7bc766 100644 --- a/libwvdrmengine/cdm/core/include/properties.h +++ b/libwvdrmengine/cdm/core/include/properties.h @@ -55,6 +55,7 @@ class Properties { static bool GetFactoryKeyboxPath(std::string* keybox); static bool GetOEMCryptoPath(std::string* library_name); static bool AlwaysUseKeySetIds(); + static bool UseProviderIdInProvisioningRequest(); static bool GetSecurityLevelDirectories(std::vector* dirs); static bool GetApplicationId(const CdmSessionId& session_id, diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h index f430cf92..25ce8d3a 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h @@ -98,6 +98,7 @@ static const std::string HLS_IV_ATTRIBUTE = "IV"; static const std::string HLS_URI_ATTRIBUTE = "URI"; static const char EMPTY_ORIGIN[] = ""; +static const char EMPTY_SPOID[] = ""; } // namespace wvcdm #endif // WVCDM_CORE_WV_CDM_CONSTANTS_H_ diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index e41227fc..2574ac4a 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -60,10 +60,11 @@ class UsagePropertySet : public CdmClientPropertySet { bool CdmEngine::seeded_ = false; -CdmEngine::CdmEngine(FileSystem* file_system) +CdmEngine::CdmEngine(FileSystem* file_system, const std::string& spoid) : cert_provisioning_(NULL), cert_provisioning_requested_security_level_(kLevelDefault), file_system_(file_system), + spoid_(spoid), usage_session_(NULL), last_usage_information_update_time_(0) { assert(file_system); @@ -718,7 +719,7 @@ CdmResponseType CdmEngine::GetProvisioningRequest( } CdmResponseType ret = cert_provisioning_->GetProvisioningRequest( cert_provisioning_requested_security_level_, cert_type, cert_authority, - file_system_->origin(), request, default_url); + file_system_->origin(), spoid_, request, default_url); if (ret != NO_ERROR) { cert_provisioning_.reset(NULL); // Release resources. } @@ -801,7 +802,7 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { return UNPROVISION_ERROR_1; } - if (!file_system_->origin().empty()) { + if (!file_system_->IsGlobal()) { if (!handle.RemoveCertificate()) { LOGE("CdmEngine::Unprovision: unable to delete certificate"); return UNPROVISION_ERROR_2; @@ -813,14 +814,14 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) { return UNPROVISION_ERROR_3; } - scoped_ptr crypto_session(new CryptoSession()); - CdmResponseType status = crypto_session->Open( + CryptoSession crypto_session; + CdmResponseType status = crypto_session.Open( security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault); if (NO_ERROR != status) { LOGE("CdmEngine::Unprovision: error opening crypto session: %d", status); return UNPROVISION_ERROR_4; } - status = crypto_session->DeleteAllUsageReports(); + status = crypto_session.DeleteAllUsageReports(); if (status != NO_ERROR) { LOGE("CdmEngine::Unprovision: error deleteing usage reports: %d", status); } diff --git a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp index c9bb9c7a..2a4b399e 100644 --- a/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp +++ b/libwvdrmengine/cdm/core/src/certificate_provisioning.cpp @@ -5,6 +5,7 @@ #include "file_store.h" #include "license_protocol.pb.h" #include "log.h" +#include "properties.h" #include "string_conversions.h" #include "wv_cdm_constants.h" @@ -68,6 +69,43 @@ bool CertificateProvisioning::GetProvisioningTokenType( } } +/* + * Fill in the appropriate field relating to stable IDs in the provisioning + * request, no more than one of |stable_id|, |provider_id|, and |spoid|. It is + * also valid (though deprecated) to fill in none of these in order to leave the + * stable ID behavior up to the provisioning server. + */ +bool CertificateProvisioning::FillStableIdField( + const std::string& origin, + const std::string& spoid, + ProvisioningRequest* request) { + if (!request) { + LOGE("CertificateProvisioning::FillStableIdField : No request buffer " + "passed to method."); + return false; + } + + if (!spoid.empty()) { + // Use the SPOID that has been pre-provided + request->set_spoid(spoid); + } else if (Properties::UseProviderIdInProvisioningRequest() && + false /* TODO(gmorgan): use provider ID. */) { + // Use the provider ID from the service certificate + + // TODO(gmorgan): use provider ID. + // request->set_provider_id(???); + } else if (origin != EMPTY_ORIGIN) { + // Legacy behavior - Concatenate Unique ID with Origin + std::string device_unique_id; + if (!crypto_session_.GetDeviceUniqueId(&device_unique_id)) { + LOGE("CryptoSession::GetStableIdField: Failure to get device unique ID"); + return false; + } + request->set_stable_id(device_unique_id + origin); + } // No else clause, by design. It is valid to do nothing. + return true; +} + /* * Return the provisioning protocol version - dictated by OEMCrypto * support for OEM certificates. @@ -90,6 +128,7 @@ SignedProvisioningMessage::ProtocolVersion CdmResponseType CertificateProvisioning::GetProvisioningRequest( SecurityLevel requested_security_level, CdmCertificateType cert_type, const std::string& cert_authority, const std::string& origin, + const std::string& spoid, CdmProvisioningRequest* request, std::string* default_url) { if (!default_url) { LOGE("GetProvisioningRequest: pointer for returning URL is NULL"); @@ -165,15 +204,8 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequest( cert_type_ = cert_type; options->set_certificate_authority(cert_authority); - // TODO(gmorgan): use provider ID. - if (origin != EMPTY_ORIGIN) { - std::string device_unique_id; - if (!crypto_session_.GetDeviceUniqueId(&device_unique_id)) { - LOGE("GetProvisioningRequest: fails to get device unique ID"); - return CERT_PROVISIONING_GET_KEYBOX_ERROR_2; - } - // TODO(gmorgan): handle provider id variants. - provisioning_request.set_stable_id(device_unique_id + origin); + if (!FillStableIdField(origin, spoid, &provisioning_request)) { + return CERT_PROVISIONING_GET_KEYBOX_ERROR_2; } std::string serialized_message; diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 000a8cac..17ba7b6a 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -218,27 +218,29 @@ bool CryptoSession::GetDeviceUniqueId(std::string* device_id) { return false; } - std::vector id; - size_t id_length = 32; - - id.resize(id_length); - LOGV("CryptoSession::GetDeviceUniqueId: Lock"); AutoLock auto_lock(crypto_lock_); if (!initialized_) { return false; } - if (pre_provision_token_type_ == kClientTokenKeybox) { + + if (pre_provision_token_type_ == kClientTokenOemCert) { + return GetTokenFromOemCert(device_id); + } else { + std::vector id; + size_t id_length = 32; + id.resize(id_length); + OEMCryptoResult sts = OEMCrypto_GetDeviceID(&id[0], &id_length, requested_security_level_); if (OEMCrypto_SUCCESS != sts) { return false; } - } - device_id->assign(reinterpret_cast(&id[0]), id_length); - return true; + device_id->assign(reinterpret_cast(&id[0]), id_length); + return true; + } } bool CryptoSession::GetApiVersion(uint32_t* version) { diff --git a/libwvdrmengine/cdm/include/cdm_identifier.h b/libwvdrmengine/cdm/include/cdm_identifier.h new file mode 100644 index 00000000..e99b9d71 --- /dev/null +++ b/libwvdrmengine/cdm/include/cdm_identifier.h @@ -0,0 +1,64 @@ +// Copyright 2016 Google Inc. All Rights Reserved. +// +// CdmIdentifier - Struct that holds all the information necessary to +// uniquely identify a CdmEngine instance in the +// WvContentDecryptionModule multiplexing layer. + +#ifndef CDM_BASE_CDM_IDENTIFIER_H_ +#define CDM_BASE_CDM_IDENTIFIER_H_ + +#include + +#include "wv_cdm_constants.h" + +namespace wvcdm { + +// CdmIdentifier contains all the information necessary to uniquely identify a +// distinct CdmEngine instance on Android. There should be a unique CdmEngine +// (and thus distinct storage space) for every combination of SPOID and origin. +struct CdmIdentifier { + // The Stable Per-Origin Identifier, or SPOID. May be blank on old, SPOID-less + // systems, in which case multiple apps with the same origin will share a + // CdmEngine and storage. + std::string spoid; + + // The origin. May be blank if the app does not set an origin, which is + // the likely behavior of most non-web-browser apps. + std::string origin; +}; + +// Provide comparison operators +inline bool operator==(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { + return lhs.spoid == rhs.spoid && lhs.origin == rhs.origin; +} + +inline bool operator!=(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { + return !(lhs == rhs); +} + +inline bool operator<(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { + return (lhs.spoid < rhs.spoid) || + ((lhs.spoid == rhs.spoid) && lhs.origin < rhs.origin); +} + +inline bool operator>(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { + return rhs < lhs; +} + +inline bool operator<=(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { + return !(lhs > rhs); +} + +inline bool operator>=(const CdmIdentifier& lhs, const CdmIdentifier& rhs) { + return !(lhs < rhs); +} + +// Provide default +static const CdmIdentifier kDefaultCdmIdentifier = { + EMPTY_SPOID, + EMPTY_ORIGIN +}; + +} // namespace wvcdm + +#endif // CDM_BASE_CDM_IDENTIFIER_H_ diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 6c3d28b4..4d53895b 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -8,6 +8,7 @@ #include #include +#include "cdm_identifier.h" #include "file_store.h" #include "lock.h" #include "timer.h" @@ -33,7 +34,7 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { // Session related methods virtual CdmResponseType OpenSession(const CdmKeySystem& key_system, CdmClientPropertySet* property_set, - const std::string& origin, + const CdmIdentifier& identifier, WvCdmEventListener* event_listener, CdmSessionId* session_id); virtual CdmResponseType CloseSession(const CdmSessionId& session_id); @@ -47,7 +48,7 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { const CdmLicenseType license_type, CdmAppParameterMap& app_parameters, CdmClientPropertySet* property_set, - const std::string& origin, + const CdmIdentifier& identifier, CdmKeyRequest* key_request); // Accept license response and extract key info. @@ -82,18 +83,18 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { virtual CdmResponseType GetProvisioningRequest( CdmCertificateType cert_type, const std::string& cert_authority, - const std::string& origin, + const CdmIdentifier& identifier, CdmProvisioningRequest* request, std::string* default_url); virtual CdmResponseType HandleProvisioningResponse( - const std::string& origin, + const CdmIdentifier& identifier, CdmProvisioningResponse& response, std::string* cert, std::string* wrapped_key); virtual CdmResponseType Unprovision(CdmSecurityLevel level, - const std::string& origin); + const CdmIdentifier& identifier); // Secure stop related methods virtual CdmResponseType GetUsageInfo(const std::string& app_id, @@ -128,8 +129,9 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { UniquePtr cdm_engine; }; - // Finds the CdmEngine instance for the given origin, creating one if needed. - CdmEngine* EnsureCdmForOrigin(const std::string& origin); + // Finds the CdmEngine instance for the given identifier, creating one if + // needed. + CdmEngine* EnsureCdmForIdentifier(const CdmIdentifier& identifier); // Finds the CdmEngine instance for the given session id, returning NULL if // not found. CdmEngine* GetCdmForSessionId(const std::string& session_id); @@ -147,7 +149,7 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler { // instance variables // This manages the lifetime of the CDM instances. - std::map cdms_; + std::map cdms_; Lock cdms_lock_; // This contains weak pointers to the CDM instances contained in |cdms_|. diff --git a/libwvdrmengine/cdm/src/file_store.cpp b/libwvdrmengine/cdm/src/file_store.cpp index 572f8eb6..9a278473 100644 --- a/libwvdrmengine/cdm/src/file_store.cpp +++ b/libwvdrmengine/cdm/src/file_store.cpp @@ -16,6 +16,7 @@ #include "file_utils.h" #include "log.h" #include "string_conversions.h" +#include "wv_cdm_constants.h" #include #include @@ -35,8 +36,8 @@ std::string GetFileNameSafeHash(const std::string& input) { return wvcdm::Base64SafeEncode(hash); } -std::string GetFileNameForOrigin(const std::string path, - const std::string origin) { +std::string GetFileNameForIdentifier(const std::string path, + const std::string identifier) { std::string file_name = path; std::string dir_path; const size_t delimiter_pos = path.rfind(kDirectoryDelimiter); @@ -45,8 +46,8 @@ std::string GetFileNameForOrigin(const std::string path, file_name = path.substr(delimiter_pos + 1); } - if (file_name == kCertificateFileName && !origin.empty()) { - const std::string hash = GetFileNameSafeHash(origin); + if (file_name == kCertificateFileName && !identifier.empty()) { + const std::string hash = GetFileNameSafeHash(identifier); file_name = kCertificateFileNamePrefix + hash + kCertificateFileNameExt; } @@ -109,7 +110,7 @@ ssize_t File::Write(const char* buffer, size_t bytes) { class FileSystem::Impl {}; -FileSystem::FileSystem() : FileSystem("", NULL) {} +FileSystem::FileSystem() : FileSystem(EMPTY_ORIGIN, NULL) {} FileSystem::FileSystem(const std::string& origin, void* /* extra_data */) : origin_(origin) { FileUtils::SecurityLevelPathBackwardCompatibility(kSecurityLevelL1); @@ -121,7 +122,7 @@ FileSystem::~FileSystem() {} File* FileSystem::Open(const std::string& in_name, int flags) { std::string open_flags; - std::string name = GetFileNameForOrigin(in_name, origin_); + std::string name = GetFileNameForIdentifier(in_name, identifier_); // create the enclosing directory if it does not exist size_t delimiter_pos = name.rfind(kDirectoryDelimiter); @@ -154,15 +155,15 @@ File* FileSystem::Open(const std::string& in_name, int flags) { } bool FileSystem::Exists(const std::string& path) { - return FileUtils::Exists(GetFileNameForOrigin(path, origin_)); + return FileUtils::Exists(GetFileNameForIdentifier(path, identifier_)); } bool FileSystem::Remove(const std::string& path) { - return FileUtils::Remove(GetFileNameForOrigin(path, origin_)); + return FileUtils::Remove(GetFileNameForIdentifier(path, identifier_)); } ssize_t FileSystem::FileSize(const std::string& in_path) { - std::string path = GetFileNameForOrigin(in_path, origin_); + std::string path = GetFileNameForIdentifier(in_path, identifier_); struct stat buf; if (stat(path.c_str(), &buf) == 0) return buf.st_size; @@ -172,4 +173,8 @@ ssize_t FileSystem::FileSize(const std::string& in_path) { void FileSystem::SetOrigin(const std::string& origin) { origin_ = origin; } +void FileSystem::SetIdentifier(const std::string& identifier) { + identifier_ = identifier; +} + } // namespace wvcdm diff --git a/libwvdrmengine/cdm/src/properties_android.cpp b/libwvdrmengine/cdm/src/properties_android.cpp index c509a3f6..b0356485 100644 --- a/libwvdrmengine/cdm/src/properties_android.cpp +++ b/libwvdrmengine/cdm/src/properties_android.cpp @@ -155,4 +155,8 @@ bool Properties::AlwaysUseKeySetIds() { return false; } +bool Properties::UseProviderIdInProvisioningRequest() { + return false; +} + } // namespace wvcdm diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index 0b335463..7ee213d3 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -44,7 +44,7 @@ bool WvContentDecryptionModule::IsHls(const std::string& init_data_type) { CdmResponseType WvContentDecryptionModule::OpenSession( const CdmKeySystem& key_system, CdmClientPropertySet* property_set, - const std::string& origin, WvCdmEventListener* event_listener, + const CdmIdentifier& identifier, WvCdmEventListener* event_listener, CdmSessionId* session_id) { if (property_set && property_set->is_session_sharing_enabled()) { AutoLock auto_lock(session_sharing_id_generation_lock_); @@ -52,7 +52,7 @@ CdmResponseType WvContentDecryptionModule::OpenSession( property_set->set_session_sharing_id(GenerateSessionSharingId()); } - CdmEngine* cdm_engine = EnsureCdmForOrigin(origin); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); CdmResponseType sts = cdm_engine->OpenSession(key_system, property_set, event_listener, session_id); if (sts == NO_ERROR) { @@ -83,9 +83,9 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest( const CdmSessionId& session_id, const CdmKeySetId& key_set_id, const std::string& init_data_type, const CdmInitData& init_data, const CdmLicenseType license_type, CdmAppParameterMap& app_parameters, - CdmClientPropertySet* property_set, const std::string& origin, + CdmClientPropertySet* property_set, const CdmIdentifier& identifier, CdmKeyRequest* key_request) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(origin); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); CdmResponseType sts; if (license_type == kLicenseTypeRelease) { sts = cdm_engine->OpenKeySetSession(key_set_id, property_set, NULL); @@ -149,7 +149,7 @@ CdmResponseType WvContentDecryptionModule::QueryStatus( SecurityLevel security_level, const std::string& key, std::string* value) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(EMPTY_ORIGIN); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); return cdm_engine->QueryStatus(security_level, key, value); } @@ -177,32 +177,32 @@ CdmResponseType WvContentDecryptionModule::QueryOemCryptoSessionId( CdmResponseType WvContentDecryptionModule::GetProvisioningRequest( CdmCertificateType cert_type, const std::string& cert_authority, - const std::string& origin, + const CdmIdentifier& identifier, CdmProvisioningRequest* request, std::string* default_url) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(origin); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); return cdm_engine->GetProvisioningRequest(cert_type, cert_authority, request, default_url); } CdmResponseType WvContentDecryptionModule::HandleProvisioningResponse( - const std::string& origin, + const CdmIdentifier& identifier, CdmProvisioningResponse& response, std::string* cert, std::string* wrapped_key) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(origin); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); return cdm_engine->HandleProvisioningResponse(response, cert, wrapped_key); } CdmResponseType WvContentDecryptionModule::Unprovision( - CdmSecurityLevel level, const std::string& origin) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(origin); + CdmSecurityLevel level, const CdmIdentifier& identifier) { + CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier); return cdm_engine->Unprovision(level); } CdmResponseType WvContentDecryptionModule::GetUsageInfo( const std::string& app_id, CdmUsageInfo* usage_info) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(EMPTY_ORIGIN); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); return cdm_engine->GetUsageInfo(app_id, usage_info); } @@ -210,19 +210,19 @@ CdmResponseType WvContentDecryptionModule::GetUsageInfo( const std::string& app_id, const CdmSecureStopId& ssid, CdmUsageInfo* usage_info) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(EMPTY_ORIGIN); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); return cdm_engine->GetUsageInfo(app_id, ssid, usage_info); } CdmResponseType WvContentDecryptionModule::ReleaseAllUsageInfo( const std::string& app_id) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(EMPTY_ORIGIN); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); return cdm_engine->ReleaseAllUsageInfo(app_id); } CdmResponseType WvContentDecryptionModule::ReleaseUsageInfo( const CdmUsageInfoReleaseMessage& message) { - CdmEngine* cdm_engine = EnsureCdmForOrigin(EMPTY_ORIGIN); + CdmEngine* cdm_engine = EnsureCdmForIdentifier(kDefaultCdmIdentifier); return cdm_engine->ReleaseUsageInfo(message); } @@ -265,15 +265,21 @@ bool WvContentDecryptionModule::IsValidServiceCertificate( WvContentDecryptionModule::CdmInfo::CdmInfo() : cdm_engine(new CdmEngine(&file_system)) {} -CdmEngine* WvContentDecryptionModule::EnsureCdmForOrigin( - const std::string& origin) { +CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier( + const CdmIdentifier& identifier) { AutoLock auto_lock(cdms_lock_); - if (cdms_.find(origin) == cdms_.end()) { - // Will create a new instance using the default constructor. - cdms_[origin].file_system.SetOrigin(origin); + if (cdms_.find(identifier) == cdms_.end()) { + // Accessing the map entry will create a new instance using the default + // constructor. We then need to provide it with two pieces of info: The + // origin provided by the app and an identifier that uniquely identifies + // this CDM. We concatenate all pieces of the CdmIdentifier in order to + // create an ID that is unique to that identifier. + cdms_[identifier].file_system.SetOrigin(identifier.origin); + cdms_[identifier].file_system.SetIdentifier( + identifier.spoid + identifier.origin); } - return cdms_[origin].cdm_engine.get(); + return cdms_[identifier].cdm_engine.get(); } CdmEngine* WvContentDecryptionModule::GetCdmForSessionId( @@ -299,7 +305,7 @@ void WvContentDecryptionModule::DisablePolicyTimer(bool force) { has_sessions = true; ++it; } else { - // The CDM is no longer used for this origin, delete it. + // The CDM is no longer used for this identifier, delete it. it = cdms_.erase(it); } } diff --git a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp index e9888f19..782527b2 100644 --- a/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp +++ b/libwvdrmengine/cdm/test/cdm_extended_duration_test.cpp @@ -7,6 +7,7 @@ #include #include +#include "cdm_identifier.h" #include "clock.h" #include "config_test_env.h" #include "device_files.h" @@ -275,8 +276,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest( session_id_, key_set_id_, "video/mp4", init_data, - license_type, app_parameters, NULL, EMPTY_ORIGIN, - &key_request)); + license_type, app_parameters, NULL, + kDefaultCdmIdentifier, &key_request)); EXPECT_EQ(kKeyRequestTypeInitial, key_request.type); key_msg_ = key_request.message; EXPECT_EQ(0u, key_request.url.size()); @@ -293,8 +294,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest( session_id_, key_set_id_, "video/mp4", init_data, - license_type, app_parameters, NULL, EMPTY_ORIGIN, - &key_request)); + license_type, app_parameters, NULL, + kDefaultCdmIdentifier, &key_request)); *server_url = key_request.url; key_msg_ = key_request.message; @@ -314,7 +315,7 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { EXPECT_EQ(expected_response, decryptor_.GenerateKeyRequest( session_id, key_set_id, "video/mp4", init_data, kLicenseTypeRelease, app_parameters, NULL, - EMPTY_ORIGIN, &key_request)); + kDefaultCdmIdentifier, &key_request)); if (expected_response == KEY_MESSAGE) { key_msg_ = key_request.message; @@ -420,13 +421,15 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { } void Unprovision() { - EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL1, EMPTY_ORIGIN)); - EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3, EMPTY_ORIGIN)); + EXPECT_EQ(NO_ERROR, + decryptor_.Unprovision(kSecurityLevelL1, kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, + decryptor_.Unprovision(kSecurityLevelL3, kDefaultCdmIdentifier)); } void Provision() { CdmResponseType status = - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); switch (status) { case NO_ERROR: @@ -444,7 +447,7 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { std::string cert_authority, cert, wrapped_key; status = decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_, + cert_type, cert_authority, kDefaultCdmIdentifier, &key_msg_, &provisioning_server_url); EXPECT_EQ(NO_ERROR, status); if (NO_ERROR != status) return; @@ -454,8 +457,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(NO_ERROR, - decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert, - &wrapped_key)); + decryptor_.HandleProvisioningResponse(kDefaultCdmIdentifier, response, + &cert, &wrapped_key)); EXPECT_EQ(0, static_cast(cert.size())); EXPECT_EQ(0, static_cast(wrapped_key.size())); decryptor_.CloseSession(session_id_); @@ -651,8 +654,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { } std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) { - decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, property_set, kDefaultCdmIdentifier, + NULL, &session_id_); CdmQueryMap query_info; EXPECT_EQ(NO_ERROR, decryptor_.QuerySessionStatus(session_id_, &query_info)); @@ -685,7 +688,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase { TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) { Provision(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); EXPECT_TRUE(!key_msg_.empty()); @@ -753,7 +757,8 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) { TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRenewalTest) { Provision(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -840,8 +845,8 @@ TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) { EXPECT_TRUE(handle.DeleteAllUsageInfoForApp("", &provider_session_tokens)); for (size_t i = 0; i < kMaxUsageTableSize + 100; ++i) { - decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, property_set, kDefaultCdmIdentifier, + NULL, &session_id_); std::string key_id = a2bs_hex( "000000427073736800000000" // blob size and pssh "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id @@ -900,7 +905,7 @@ TEST_F(WvCdmExtendedDurationTest, DISABLED_AutomatedOfflineSessionReleaseTest) { std::set key_set_id_map; for (uint32_t i = 0; i < num_key_set_ids; ++i) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline); VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false); @@ -914,7 +919,7 @@ TEST_F(WvCdmExtendedDurationTest, DISABLED_AutomatedOfflineSessionReleaseTest) { for (iter = key_set_id_map.begin(); iter != key_set_id_map.end(); ++iter) { session_id_.clear(); key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, *iter)); decryptor_.CloseSession(session_id_); @@ -957,7 +962,8 @@ TEST_P(WvCdmStreamingNoPstTest, UsageTest) { Unprovision(); Provision(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -1031,7 +1037,8 @@ TEST_P(WvCdmStreamingPstTest, UsageTest) { Unprovision(); Provision(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(kStreamingClip1PstInitData, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -1096,7 +1103,8 @@ TEST_P(WvCdmStreamingUsageReportTest, UsageTest) { Unprovision(); Provision(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(kStreamingClip1PstInitData, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -1192,7 +1200,8 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) { Unprovision(); Provision(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(kOfflineClip2PstInitData, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -1215,7 +1224,8 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) { for (size_t i = 0; i < GetParam(); ++i) { session_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); // Query and validate usage information @@ -1258,7 +1268,8 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) { } session_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); // Query and validate usage information diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index 57fb4d5d..071a5546 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -8,6 +8,7 @@ #include #include +#include "cdm_identifier.h" #include "config_test_env.h" #include "device_files.h" #include "file_store.h" @@ -48,7 +49,10 @@ const int kHttpOk = 200; const int kHttpBadRequest = 400; const int kHttpInternalServerError = 500; -const char kOrigin[] = "com.example"; +const wvcdm::CdmIdentifier kExampleIdentifier = { + wvcdm::EMPTY_SPOID, + "com.example" +}; // Protobuf generated classes using video_widevine::LicenseIdentification; @@ -1038,8 +1042,8 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { EXPECT_EQ(expected_response, decryptor_.GenerateKeyRequest( session_id_, key_set_id, init_data_type, init_data, - license_type, app_parameters, property_set, EMPTY_ORIGIN, - &key_request)); + license_type, app_parameters, property_set, + kDefaultCdmIdentifier, &key_request)); key_msg_ = key_request.message; EXPECT_EQ(0u, key_request.url.size()); } @@ -1061,7 +1065,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { EXPECT_EQ(wvcdm::KEY_MESSAGE, decryptor_.GenerateKeyRequest( session_id_, key_set_id_, "video/mp4", init_data, - license_type, app_parameters, NULL, EMPTY_ORIGIN, + license_type, app_parameters, NULL, kDefaultCdmIdentifier, &key_request)); key_msg_ = key_request.message; *server_url = key_request.url; @@ -1086,7 +1090,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { decryptor_.GenerateKeyRequest( session_id, key_set_id, "video/mp4", init_data, kLicenseTypeRelease, app_parameters, property_set, - EMPTY_ORIGIN, &key_request)); + kDefaultCdmIdentifier, &key_request)); key_msg_ = key_request.message; EXPECT_EQ(kKeyRequestTypeRelease, key_request.type); if (key_msg) *key_msg = key_request.message; @@ -1194,15 +1198,17 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { } void Unprovision() { - EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL1, EMPTY_ORIGIN)); - EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3, EMPTY_ORIGIN)); + EXPECT_EQ(NO_ERROR, + decryptor_.Unprovision(kSecurityLevelL1, kDefaultCdmIdentifier)); + EXPECT_EQ(NO_ERROR, + decryptor_.Unprovision(kSecurityLevelL3, kDefaultCdmIdentifier)); } void Provision(SecurityLevel level) { - Provision(EMPTY_ORIGIN, level); + Provision(kDefaultCdmIdentifier, level); } - void Provision(const std::string& origin, SecurityLevel level) { + void Provision(const CdmIdentifier& identifier, SecurityLevel level) { TestWvCdmClientPropertySet property_set_L3; TestWvCdmClientPropertySet* property_set = NULL; @@ -1212,7 +1218,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { } CdmResponseType status = decryptor_.OpenSession( - g_key_system, property_set, origin, NULL, &session_id_); + g_key_system, property_set, identifier, NULL, &session_id_); switch (status) { case NO_ERROR: decryptor_.CloseSession(session_id_); @@ -1229,7 +1235,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { std::string cert_authority, cert, wrapped_key; status = decryptor_.GetProvisioningRequest(cert_type, cert_authority, - origin, &key_msg_, + identifier, &key_msg_, &provisioning_server_url); EXPECT_EQ(wvcdm::NO_ERROR, status); if (NO_ERROR != status) return; @@ -1239,7 +1245,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(wvcdm::NO_ERROR, - decryptor_.HandleProvisioningResponse(origin, response, + decryptor_.HandleProvisioningResponse(identifier, response, &cert, &wrapped_key)); EXPECT_EQ(0, static_cast(cert.size())); EXPECT_EQ(0, static_cast(wrapped_key.size())); @@ -1249,8 +1255,9 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) { EXPECT_EQ(NO_ERROR, - decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, - NULL, &session_id_)); + decryptor_.OpenSession(g_key_system, property_set, + kDefaultCdmIdentifier, NULL, + &session_id_)); CdmQueryMap query_info; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.QuerySessionStatus(session_id_, &query_info)); @@ -1298,39 +1305,44 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase { }; TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg_, &provisioning_server_url)); + cert_type, cert_authority, + kDefaultCdmIdentifier, &key_msg_, + &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); std::string response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); EXPECT_EQ(0, static_cast(cert.size())); EXPECT_EQ(0, static_cast(wrapped_key.size())); decryptor_.CloseSession(session_id_); } TEST_F(WvCdmRequestLicenseTest, PerOriginProvisioningTest) { - EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3, kOrigin)); + EXPECT_EQ(NO_ERROR, + decryptor_.Unprovision(kSecurityLevelL3, kExampleIdentifier)); - // Verify the empty origin is provisioned. + // Verify the global identifier is provisioned. EXPECT_EQ(wvcdm::NO_ERROR, - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, - &session_id_)); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, + NULL, &session_id_)); decryptor_.CloseSession(session_id_); - // The other origin should not be provisioned. + // The other identifier should not be provisioned. EXPECT_EQ( wvcdm::NEED_PROVISIONING, - decryptor_.OpenSession(g_key_system, NULL, kOrigin, NULL, &session_id_)); + decryptor_.OpenSession(g_key_system, NULL, kExampleIdentifier, NULL, + &session_id_)); } TEST_F(WvCdmRequestLicenseTest, PerOriginProvisioningSupportsOldPaths) { @@ -1338,12 +1350,14 @@ TEST_F(WvCdmRequestLicenseTest, PerOriginProvisioningSupportsOldPaths) { // not break existing clients if we decide to change the naming/paths of // certificates. const char kOldFileName[] = "cert0LF0GfM75iqlNA_sByaQMA==.bin"; - ASSERT_EQ("com.example", kOrigin); + ASSERT_EQ("com.example", kExampleIdentifier.origin); // Unprovision the device and delete all files. - EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3, kOrigin)); - EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(kSecurityLevelL3, EMPTY_ORIGIN)); - Provision(kOrigin, kLevel3); + EXPECT_EQ(NO_ERROR, + decryptor_.Unprovision(kSecurityLevelL3, kExampleIdentifier)); + EXPECT_EQ(NO_ERROR, + decryptor_.Unprovision(kSecurityLevelL3, kDefaultCdmIdentifier)); + Provision(kExampleIdentifier, kLevel3); std::string base_path; ASSERT_TRUE(Properties::GetDeviceFilesBasePath(kSecurityLevelL3, &base_path)); @@ -1354,8 +1368,8 @@ TEST_F(WvCdmRequestLicenseTest, PerOriginProvisioningSupportsOldPaths) { ASSERT_EQ(1u, files.size()); EXPECT_EQ(kOldFileName, files[0]); - // Reprovision the empty origin. - Provision(EMPTY_ORIGIN, kLevel3); + // Reprovision the default identifier. + Provision(kDefaultCdmIdentifier, kLevel3); } TEST_F(WvCdmRequestLicenseTest, UnprovisionTest) { @@ -1367,25 +1381,29 @@ TEST_F(WvCdmRequestLicenseTest, UnprovisionTest) { std::string wrapped_private_key; EXPECT_TRUE(handle.RetrieveCertificate(&certificate, &wrapped_private_key)); - EXPECT_EQ(NO_ERROR, decryptor_.Unprovision(security_level, EMPTY_ORIGIN)); + EXPECT_EQ(NO_ERROR, + decryptor_.Unprovision(security_level, kDefaultCdmIdentifier)); EXPECT_FALSE(handle.RetrieveCertificate(&certificate, &wrapped_private_key)); } TEST_F(WvCdmRequestLicenseTest, ProvisioningInterposedRetryTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; CdmKeyMessage key_msg1, key_msg2; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg1, &provisioning_server_url)); + cert_type, cert_authority, + kDefaultCdmIdentifier, &key_msg1, + &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg2, &provisioning_server_url)); + cert_type, cert_authority, + kDefaultCdmIdentifier, &key_msg2, + &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); key_msg_ = key_msg2; @@ -1393,7 +1411,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterposedRetryTest) { GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); EXPECT_EQ(0, static_cast(cert.size())); EXPECT_EQ(0, static_cast(wrapped_key.size())); @@ -1401,7 +1420,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterposedRetryTest) { response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(wvcdm::NO_ERROR, - decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert, + decryptor_.HandleProvisioningResponse(kDefaultCdmIdentifier, + response, &cert, &wrapped_key)); EXPECT_EQ(0, static_cast(cert.size())); EXPECT_EQ(0, static_cast(wrapped_key.size())); @@ -1409,20 +1429,23 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterposedRetryTest) { } TEST_F(WvCdmRequestLicenseTest, ProvisioningInterspersedRetryTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; std::string key_msg1, key_msg2; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg1, &provisioning_server_url)); + cert_type, cert_authority, + kDefaultCdmIdentifier, &key_msg1, + &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg2, &provisioning_server_url)); + cert_type, cert_authority, + kDefaultCdmIdentifier, &key_msg2, + &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); key_msg_ = key_msg1; @@ -1430,7 +1453,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterspersedRetryTest) { GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(wvcdm::CERT_PROVISIONING_RESPONSE_ERROR_6, - decryptor_.HandleProvisioningResponse(EMPTY_ORIGIN, response, &cert, + decryptor_.HandleProvisioningResponse(kDefaultCdmIdentifier, + response, &cert, &wrapped_key)); EXPECT_EQ(0, static_cast(cert.size())); EXPECT_EQ(0, static_cast(wrapped_key.size())); @@ -1439,7 +1463,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterspersedRetryTest) { response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); EXPECT_EQ(0, static_cast(cert.size())); EXPECT_EQ(0, static_cast(wrapped_key.size())); @@ -1447,7 +1472,8 @@ TEST_F(WvCdmRequestLicenseTest, ProvisioningInterspersedRetryTest) { } TEST_F(WvCdmRequestLicenseTest, DISABLED_X509ProvisioningTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateX509; // TODO(rfrias): insert appropriate CA here @@ -1455,15 +1481,17 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_X509ProvisioningTest) { std::string cert, wrapped_key; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg_, &provisioning_server_url)); + cert_type, cert_authority, + kDefaultCdmIdentifier, &key_msg_, + &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); std::string response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); EXPECT_NE(0, static_cast(cert.size())); EXPECT_NE(0, static_cast(wrapped_key.size())); decryptor_.CloseSession(session_id_); @@ -1479,37 +1507,40 @@ TEST_F(WvCdmRequestLicenseTest, PropertySetTest) { property_set_L1.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L1); property_set_L1.set_use_privacy_mode(true); - decryptor_.OpenSession(g_key_system, &property_set_L1, EMPTY_ORIGIN, NULL, - &session_id_L1); + decryptor_.OpenSession(g_key_system, &property_set_L1, kDefaultCdmIdentifier, + NULL, &session_id_L1); property_set_L3.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3); property_set_L3.set_use_privacy_mode(false); CdmResponseType sts = decryptor_.OpenSession( - g_key_system, &property_set_L3, EMPTY_ORIGIN, NULL, &session_id_L3); + g_key_system, &property_set_L3, kDefaultCdmIdentifier, NULL, + &session_id_L3); if (NEED_PROVISIONING == sts) { std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_, - &provisioning_server_url)); + cert_type, cert_authority, kDefaultCdmIdentifier, + &key_msg_, &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); std::string response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set_L3, - EMPTY_ORIGIN, NULL, &session_id_L3)); + kDefaultCdmIdentifier, NULL, + &session_id_L3)); } else { EXPECT_EQ(NO_ERROR, sts); } property_set_Ln.set_security_level(""); - decryptor_.OpenSession(g_key_system, &property_set_Ln, EMPTY_ORIGIN, NULL, - &session_id_Ln); + decryptor_.OpenSession(g_key_system, &property_set_Ln, kDefaultCdmIdentifier, + NULL, &session_id_Ln); CdmQueryMap query_info; EXPECT_EQ(wvcdm::NO_ERROR, @@ -1560,23 +1591,25 @@ TEST_F(WvCdmRequestLicenseTest, ForceL3Test) { EXPECT_TRUE(handle.DeleteAllFiles()); EXPECT_EQ(NEED_PROVISIONING, - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, - NULL, &session_id_)); + decryptor_.OpenSession(g_key_system, &property_set, + kDefaultCdmIdentifier, NULL, &session_id_)); std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_, - &provisioning_server_url)); + cert_type, cert_authority, kDefaultCdmIdentifier, + &key_msg_, &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); std::string response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set, - EMPTY_ORIGIN, NULL, &session_id_)); + kDefaultCdmIdentifier, NULL, + &session_id_)); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); @@ -1586,8 +1619,8 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeTest) { TestWvCdmClientPropertySet property_set; property_set.set_use_privacy_mode(true); - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); std::string resp = GetKeyRequestResponse(g_license_server, g_client_auth); @@ -1603,22 +1636,24 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeWithServiceCertificateTest) { property_set.set_use_privacy_mode(true); property_set.set_service_certificate(a2bs_hex(g_service_certificate)); - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); } TEST_F(WvCdmRequestLicenseTest, BaseMessageTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); GetKeyRequestResponse(g_license_server, g_client_auth); decryptor_.CloseSession(session_id_); } TEST_F(WvCdmRequestLicenseTest, WrongMessageTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); std::string wrong_message = wvcdm::a2bs_hex(g_wrong_key_id); GenerateKeyRequest(wrong_message, kLicenseTypeStreaming); @@ -1646,7 +1681,8 @@ TEST_F(WvCdmRequestLicenseTest, WrongMessageTest) { } TEST_F(WvCdmRequestLicenseTest, AddStreamingKeyTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); decryptor_.CloseSession(session_id_); @@ -1661,7 +1697,8 @@ TEST_F(WvCdmRequestLicenseTest, AddKeyOfflineTest) { std::string client_auth; GetOfflineConfiguration(&key_id, &client_auth); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); decryptor_.CloseSession(session_id_); @@ -1676,7 +1713,8 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeyTest) { std::string client_auth; GetOfflineConfiguration(&key_id, &client_auth); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); @@ -1685,7 +1723,8 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeyTest) { decryptor_.CloseSession(session_id_); session_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); } @@ -1699,7 +1738,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) { std::string client_auth; GetOfflineConfiguration(&key_id, &client_auth); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); @@ -1709,7 +1749,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) { session_id_.clear(); key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); @@ -1733,7 +1774,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) { GetOfflineConfiguration(&key_id, &client_auth); key_id[key_id.size()-1] = '1'; - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); @@ -1743,7 +1785,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) { session_id_.clear(); key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); @@ -1786,7 +1829,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) { std::string client_auth; GetOfflineConfiguration(&key_id, &client_auth); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); @@ -1796,7 +1840,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) { session_id_.clear(); key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); @@ -1805,7 +1850,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) { GenerateKeyRelease(key_set_id); session_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(wvcdm::GET_RELEASED_LICENSE_ERROR, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); @@ -1829,30 +1875,32 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) { GetOfflineConfiguration(&key_id, &client_auth); CdmResponseType sts = decryptor_.OpenSession( - g_key_system, &property_set, EMPTY_ORIGIN, NULL, &session_id_); + g_key_system, &property_set, kDefaultCdmIdentifier, NULL, &session_id_); if (NEED_PROVISIONING == sts) { std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_, - &provisioning_server_url)); + cert_type, cert_authority, kDefaultCdmIdentifier, + &key_msg_, &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); std::string response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); EXPECT_EQ(NO_ERROR, - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, - NULL, &session_id_)); + decryptor_.OpenSession(g_key_system, &property_set, + kDefaultCdmIdentifier, NULL, + &session_id_)); } else { EXPECT_EQ(NO_ERROR, sts); } - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline, &property_set); VerifyKeyRequestResponse(g_license_server, client_auth, false); @@ -1862,8 +1910,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) { session_id_.clear(); key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); @@ -1872,8 +1920,8 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) { GenerateKeyRelease(key_set_id, &property_set, NULL); session_id_.clear(); - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); EXPECT_EQ(wvcdm::GET_RELEASED_LICENSE_ERROR, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); @@ -1894,7 +1942,8 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) { std::string client_auth; GetOfflineConfiguration(&key_id, &client_auth); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); @@ -1905,7 +1954,7 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) { session_id_.clear(); key_set_id_.clear(); StrictMock listener; - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, &listener, + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, &listener, &session_id_); CdmSessionId restore_session_id = session_id_; EXPECT_CALL( @@ -1945,7 +1994,8 @@ TEST_F(WvCdmRequestLicenseTest, AutomatedOfflineSessionReleaseTest) { std::string client_auth; GetOfflineConfiguration(&key_id, &client_auth); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); @@ -1955,7 +2005,8 @@ TEST_F(WvCdmRequestLicenseTest, AutomatedOfflineSessionReleaseTest) { session_id_.clear(); key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); @@ -1988,7 +2039,8 @@ TEST_F(WvCdmRequestLicenseTest, AutomatedOfflineSessionReleaseTest) { } TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewal) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -2000,7 +2052,8 @@ TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewal) { } TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewalProhibited) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); std::string key_id = a2bs_hex( // streaming_clip11 "000000427073736800000000" // blob size and pssh "EDEF8BA979D64ACEA3C827DCD51D21ED00000023" // Widevine system id @@ -2016,7 +2069,7 @@ TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewalProhibited) { decryptor_.GenerateKeyRequest( session_id_, key_set_id_, "video/mp4", init_data, kLicenseTypeStreaming, app_parameters, NULL, - EMPTY_ORIGIN, &key_request)); + kDefaultCdmIdentifier, &key_request)); key_msg_ = key_request.message; decryptor_.CloseSession(session_id_); } @@ -2027,7 +2080,8 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) { std::string client_auth; GetOfflineConfiguration(&key_id, &client_auth); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); @@ -2039,8 +2093,9 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) { } TEST_F(WvCdmRequestLicenseTest, RemoveKeys) { - ASSERT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, - NULL, &session_id_)); + ASSERT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, NULL, + kDefaultCdmIdentifier, NULL, + &session_id_)); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); ASSERT_EQ(NO_ERROR, decryptor_.RemoveKeys(session_id_)); @@ -2081,8 +2136,8 @@ TEST_P(WvCdmStreamingLicenseRenewalTest, WithClientId) { if (config->specify_service_certificate) property_set.set_service_certificate(a2bs_hex(g_service_certificate)); } - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); GenerateKeyRequest(key_id, app_parameters, kLicenseTypeStreaming, &property_set); if (config->enable_privacy_mode && !config->specify_service_certificate) { @@ -2211,8 +2266,8 @@ TEST_P(WvCdmOfflineLicenseReleaseTest, WithClientId) { if (config->specify_service_certificate) property_set.set_service_certificate(a2bs_hex(g_service_certificate)); } - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); GenerateKeyRequest(key_id, app_parameters, kLicenseTypeOffline, NULL); if (config->enable_privacy_mode && !config->specify_service_certificate) { std::string resp = GetKeyRequestResponse(g_license_server, client_auth); @@ -2248,8 +2303,8 @@ TEST_P(WvCdmOfflineLicenseReleaseTest, WithClientId) { session_id_.clear(); key_set_id_.clear(); - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); @@ -2347,8 +2402,8 @@ TEST_P(WvCdmUsageTest, WithClientId) { TestWvCdmClientPropertySet property_set; SubSampleInfo* data = &usage_info_sub_samples_icp[0]; - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); GenerateKeyRequest(key_id, app_parameters, kLicenseTypeStreaming, &property_set); @@ -2446,7 +2501,8 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) { EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(app_id, &psts)); SubSampleInfo* data = &usage_info_sub_samples_icp[0]; - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); std::string key_id = a2bs_hex( "000000427073736800000000" // blob size and pssh "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id @@ -2529,8 +2585,8 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) { for (size_t i = 0; i < usage_info_data->usage_info; ++i) { SubSampleInfo* data = usage_info_data->sub_sample + i; - decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, property_set, kDefaultCdmIdentifier, + NULL, &session_id_); std::string key_id = a2bs_hex( "000000427073736800000000" // blob size and pssh "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id @@ -2604,8 +2660,8 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) { for (size_t i = 0; i < N_ELEM(usage_info_sub_samples_icp); ++i) { SubSampleInfo* data = usage_info_sub_samples_icp + i; property_set.set_app_id(i % 2 == 0 ? app_id_empty : app_id_not_empty); - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); std::string key_id = a2bs_hex( "000000427073736800000000" // blob size and pssh "EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id @@ -2680,7 +2736,8 @@ TEST_F(WvCdmRequestLicenseTest, QueryKeyStatus) { Unprovision(); Provision(kLevelDefault); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -2913,7 +2970,8 @@ TEST_F(WvCdmRequestLicenseTest, QueryOemCryptoSessionId) { Unprovision(); Provision(kLevelDefault); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -2977,19 +3035,22 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) { } // Provision the device to create any required files. - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); std::string provisioning_server_url; CdmCertificateType cert_type = kCertificateWidevine; std::string cert_authority, cert, wrapped_key; EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, - &key_msg_, &provisioning_server_url)); + cert_type, cert_authority, + kDefaultCdmIdentifier, &key_msg_, + &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); std::string response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); decryptor_.CloseSession(session_id_); std::vector files; @@ -2997,7 +3058,8 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) { size_t number_of_files = files.size(); // Create an offline license to create license files. - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, client_auth, false); CdmKeySetId key_set_id = key_set_id_; @@ -3030,11 +3092,13 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) { // Restore persistent license, retrieve L1, L3 streaming licenses to verify session_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); decryptor_.CloseSession(session_id_); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, client_auth, false); decryptor_.CloseSession(session_id_); @@ -3045,26 +3109,29 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) { property_set.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3); EXPECT_EQ(wvcdm::NEED_PROVISIONING, - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, - NULL, &session_id_)); + decryptor_.OpenSession(g_key_system, &property_set, + kDefaultCdmIdentifier, NULL, &session_id_)); EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest( - cert_type, cert_authority, EMPTY_ORIGIN, &key_msg_, - &provisioning_server_url)); + cert_type, cert_authority, kDefaultCdmIdentifier, + &key_msg_, &provisioning_server_url)); EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url()); response = GetCertRequestResponse(g_config->provisioning_server_url()); EXPECT_NE(0, static_cast(response.size())); EXPECT_EQ(NO_ERROR, decryptor_.HandleProvisioningResponse( - EMPTY_ORIGIN, response, &cert, &wrapped_key)); + kDefaultCdmIdentifier, response, &cert, + &wrapped_key)); EXPECT_EQ(NO_ERROR, decryptor_.OpenSession(g_key_system, &property_set, - EMPTY_ORIGIN, NULL, &session_id_)); + kDefaultCdmIdentifier, NULL, + &session_id_)); GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, client_auth, false); decryptor_.CloseSession(session_id_); } TEST_F(WvCdmRequestLicenseTest, DISABLED_OfflineLicenseDecryptionTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -3117,7 +3184,8 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_OfflineLicenseDecryptionTest) { } TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); GenerateKeyRequest(g_key_id, kLicenseTypeOffline); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); CdmKeySetId key_set_id = key_set_id_; @@ -3125,7 +3193,8 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) { decryptor_.CloseSession(session_id_); session_id_.clear(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id)); /* // key 1, encrypted, 256b @@ -3242,8 +3311,8 @@ TEST_P(WvCdmSessionSharingTest, SessionSharingTest) { property_set.set_session_sharing_mode( session_sharing_info->session_sharing_enabled); - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); CdmSessionId gp_session_id_1 = session_id_; GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -3256,8 +3325,8 @@ TEST_P(WvCdmSessionSharingTest, SessionSharingTest) { "edef8ba979d64acea3c827dcd51d21ed00000014" // Widevine system id "08011210bdf1cb4fffc6506b8b7945b0bd2917fb"); // pssh data - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); CdmSessionId gp_session_id_2 = session_id_; GenerateKeyRequest(gp_key_id2, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, gp_client_auth2, false); @@ -3301,8 +3370,8 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) { "EDEF8BA979D64ACEA3C827DCD51D21ED00000014" // Widevine system id "0801121030313233343536373839616263646566"); // pssh data - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); CdmSessionId session_id1 = session_id_; GenerateKeyRequest(init_data1, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -3315,8 +3384,8 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) { "edef8ba979d64acea3c827dcd51d21ed00000014" // Widevine system id "08011210bdf1cb4fffc6506b8b7945b0bd2917fb"); // pssh data - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); CdmSessionId session_id2 = session_id_; GenerateKeyRequest(init_data2, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, gp_client_auth2, false); @@ -3337,8 +3406,8 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) { sleep(kSingleEncryptedSubSampleIcpLicenseDurationExpiration - kSingleEncryptedSubSampleIcpLicenseExpirationWindow); - decryptor_.OpenSession(g_key_system, &property_set, EMPTY_ORIGIN, NULL, - &session_id_); + decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier, + NULL, &session_id_); CdmSessionId session_id3 = session_id_; GenerateKeyRequest(init_data1, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -3362,7 +3431,8 @@ TEST_F(WvCdmRequestLicenseTest, DecryptionKeyExpiredTest) { "EDEF8BA979D64ACEA3C827DCD51D21ED00000014" // Widevine system id "0801121030313233343536373839616263646566"); // pssh data SubSampleInfo* data = &single_encrypted_sub_sample_short_expiry; - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); if (data->retrieve_key) { GenerateKeyRequest(kCpKeyId, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -3389,7 +3459,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionKeyChangeNotificationTest) { DecryptCallbackTester decrypt_callback( &decryptor_, &single_encrypted_sub_sample_short_expiry); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, &listener, + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, &listener, &session_id_); EXPECT_CALL( listener, @@ -3417,7 +3487,8 @@ class WvCdmDecryptionTest TEST_P(WvCdmDecryptionTest, DecryptionTest) { SubSampleInfo* data = GetParam(); - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); if (data->retrieve_key) { GenerateKeyRequest(g_key_id, kLicenseTypeStreaming); VerifyKeyRequestResponse(g_license_server, g_client_auth, false); @@ -3480,7 +3551,8 @@ TEST(VersionNumberTest, VersionNumberChangeCanary) { } TEST_F(WvCdmRequestLicenseTest, AddHlsStreamingKeyTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); CdmAppParameterMap app_parameters; GenerateKeyRequest(wvcdm::KEY_MESSAGE, HLS_INIT_DATA_FORMAT, kAttributeListSampleAes, app_parameters, @@ -3496,7 +3568,8 @@ class WvHlsInitDataTest public ::testing::WithParamInterface {}; TEST_P(WvHlsInitDataTest, InvalidHlsFormatTest) { - decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_); + decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL, + &session_id_); CdmAppParameterMap app_parameters; std::string init_data = GetParam(); GenerateKeyRequest(wvcdm::INIT_DATA_NOT_FOUND, HLS_INIT_DATA_FORMAT, @@ -3522,8 +3595,8 @@ TEST_P(WvHlsDecryptionTest, HlsDecryptionTest) { HlsDecryptionInfo* info = GetParam(); TestWvCdmHlsEventListener listener; - decryptor_.OpenSession(g_key_system, &client_property_set, EMPTY_ORIGIN, - &listener, &session_id_); + decryptor_.OpenSession(g_key_system, &client_property_set, + kDefaultCdmIdentifier, &listener, &session_id_); CdmAppParameterMap app_parameters; GenerateKeyRequest(wvcdm::KEY_MESSAGE, HLS_INIT_DATA_FORMAT, info->attribute_list, app_parameters, @@ -3576,8 +3649,8 @@ TEST_P(WvHlsFourCCBackwardCompatibilityTest, HlsDecryptionTest) { HlsDecryptionInfo* info = GetParam(); TestWvCdmHlsEventListener listener; - decryptor_.OpenSession(g_key_system, &client_property_set, EMPTY_ORIGIN, - &listener, &session_id_); + decryptor_.OpenSession(g_key_system, &client_property_set, + kDefaultCdmIdentifier, &listener, &session_id_); CdmAppParameterMap app_parameters; GenerateKeyRequest(wvcdm::KEY_MESSAGE, ISO_BMFF_VIDEO_MIME_TYPE, info->attribute_list, app_parameters, diff --git a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h index ae7e016a..6a4d5f0d 100644 --- a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h @@ -9,6 +9,7 @@ #include #include "cdm_client_property_set.h" +#include "cdm_identifier.h" #include "media/drm/DrmAPI.h" #include "media/stagefright/foundation/ABase.h" #include "media/stagefright/foundation/AString.h" @@ -31,6 +32,7 @@ using android::status_t; using android::String8; using android::Vector; using std::map; +using wvcdm::CdmIdentifier; using wvcdm::CdmKeyStatusMap; using wvcdm::CdmSessionId; using wvcdm::CdmResponseType; @@ -263,9 +265,10 @@ class WVDrmPlugin : public android::DrmPlugin, android::sp const mCDM; WVGenericCryptoInterface* mCrypto; - std::string mOrigin; map mCryptoSessions; + CdmIdentifier mCdmIdentifier; + status_t queryProperty(const std::string& property, std::string& stringValue) const; @@ -289,9 +292,7 @@ class WVDrmPlugin : public android::DrmPlugin, bool initDataResemblesPSSH(const Vector& initData); - status_t unprovision(const std::string& origin); - - const char* determineOrigin() const; + status_t unprovision(const CdmIdentifier& identifier); }; } // namespace wvdrm diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index d60e0bb4..ea2737f0 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -76,7 +76,10 @@ DrmPlugin::KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { WVDrmPlugin::WVDrmPlugin(const sp& cdm, WVGenericCryptoInterface* crypto) - : mCDM(cdm), mCrypto(crypto), mOrigin(), mCryptoSessions() {} + : mCDM(cdm), + mCrypto(crypto), + mCryptoSessions(), + mCdmIdentifier(kDefaultCdmIdentifier) {} WVDrmPlugin::~WVDrmPlugin() { typedef map::iterator mapIterator; @@ -94,7 +97,7 @@ WVDrmPlugin::~WVDrmPlugin() { status_t WVDrmPlugin::openSession(Vector& sessionId) { CdmSessionId cdmSessionId; CdmResponseType res = - mCDM->OpenSession("com.widevine", &mPropertySet, determineOrigin(), this, + mCDM->OpenSession("com.widevine", &mPropertySet, mCdmIdentifier, this, &cdmSessionId); if (!isCdmResponseTypeSuccess(res)) { @@ -222,7 +225,7 @@ status_t WVDrmPlugin::getKeyRequest( CdmKeyRequest keyRequest; CdmResponseType res = mCDM->GenerateKeyRequest( cdmSessionId, cdmKeySetId, cdmInitDataType, processedInitData, - cdmLicenseType, cdmParameters, &mPropertySet, determineOrigin(), + cdmLicenseType, cdmParameters, &mPropertySet, mCdmIdentifier, &keyRequest); *keyRequestType = ConvertFromCdmKeyRequestType(keyRequest.type); @@ -346,7 +349,7 @@ status_t WVDrmPlugin::getProvisionRequest(const String8& cert_type, CdmResponseType res = mCDM->GetProvisioningRequest(cdmCertType, cdmCertAuthority, - determineOrigin(), + mCdmIdentifier, &cdmProvisionRequest, &cdmDefaultUrl); @@ -365,13 +368,14 @@ status_t WVDrmPlugin::provideProvisionResponse( Vector& wrapped_key) { CdmProvisioningResponse cdmResponse(response.begin(), response.end()); if (cdmResponse == kSpecialUnprovisionResponse) { - const std::string origin = determineOrigin(); - if (origin == EMPTY_ORIGIN) return kErrorNoOriginSpecified; - return unprovision(origin); + if (mCdmIdentifier == kDefaultCdmIdentifier) { + return kErrorNoOriginSpecified; + } + return unprovision(mCdmIdentifier); } else { string cdmCertificate; string cdmWrappedKey; - CdmResponseType res = mCDM->HandleProvisioningResponse(determineOrigin(), + CdmResponseType res = mCDM->HandleProvisioningResponse(mCdmIdentifier, cdmResponse, &cdmCertificate, &cdmWrappedKey); @@ -385,7 +389,7 @@ status_t WVDrmPlugin::provideProvisionResponse( } status_t WVDrmPlugin::unprovisionDevice() { - return unprovision(EMPTY_ORIGIN); + return unprovision(kDefaultCdmIdentifier); } status_t WVDrmPlugin::getSecureStop(const Vector& ssid, @@ -483,7 +487,7 @@ status_t WVDrmPlugin::getPropertyString(const String8& name, } else if (name == "appId") { value = mPropertySet.app_id().c_str(); } else if (name == "origin") { - value = mOrigin.c_str(); + value = mCdmIdentifier.origin.c_str(); } else { ALOGE("App requested unknown string property %s", name.string()); return android::ERROR_DRM_CANNOT_HANDLE; @@ -570,11 +574,11 @@ status_t WVDrmPlugin::setPropertyString(const String8& name, return kErrorSessionIsOpen; } } else if (name == "origin") { - if (mCryptoSessions.size() == 0) { - mOrigin = value.string(); - } else { + if (mCryptoSessions.size() != 0) { ALOGE("App tried to set the origin while sessions are opened."); return kErrorSessionIsOpen; + } else { + mCdmIdentifier.origin = value.string(); } } else { ALOGE("App set unknown string property %s", name.string()); @@ -977,9 +981,9 @@ bool WVDrmPlugin::initDataResemblesPSSH(const Vector& initData) { return id == kPsshTag; } -status_t WVDrmPlugin::unprovision(const std::string& origin) { - CdmResponseType res1 = mCDM->Unprovision(kSecurityLevelL1, origin); - CdmResponseType res3 = mCDM->Unprovision(kSecurityLevelL3, origin); +status_t WVDrmPlugin::unprovision(const CdmIdentifier& identifier) { + CdmResponseType res1 = mCDM->Unprovision(kSecurityLevelL1, identifier); + CdmResponseType res3 = mCDM->Unprovision(kSecurityLevelL3, identifier); if (!isCdmResponseTypeSuccess(res1)) { return mapCdmResponseType(res1); @@ -990,8 +994,4 @@ status_t WVDrmPlugin::unprovision(const std::string& origin) { } } -const char* WVDrmPlugin::determineOrigin() const { - return mOrigin.empty() ? EMPTY_ORIGIN : mOrigin.c_str(); -} - } // namespace wvdrm diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index a98c20b3..286ec0d1 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -38,7 +38,7 @@ class MockCDM : public WvContentDecryptionModule { public: MOCK_METHOD5(OpenSession, CdmResponseType(const CdmKeySystem&, CdmClientPropertySet*, - const std::string&, + const CdmIdentifier&, WvCdmEventListener*, CdmSessionId*)); @@ -48,7 +48,7 @@ class MockCDM : public WvContentDecryptionModule { CdmResponseType(const CdmSessionId&, const CdmKeySetId&, const std::string&, const CdmInitData&, const CdmLicenseType, CdmAppParameterMap&, - CdmClientPropertySet*, const std::string&, + CdmClientPropertySet*, const CdmIdentifier&, CdmKeyRequest*)); MOCK_METHOD3(AddKey, CdmResponseType(const CdmSessionId&, @@ -71,16 +71,16 @@ class MockCDM : public WvContentDecryptionModule { MOCK_METHOD5(GetProvisioningRequest, CdmResponseType(CdmCertificateType, const std::string&, - const std::string&, + const CdmIdentifier&, CdmProvisioningRequest*, std::string*)); MOCK_METHOD4(HandleProvisioningResponse, - CdmResponseType(const std::string&, CdmProvisioningResponse&, + CdmResponseType(const CdmIdentifier&, CdmProvisioningResponse&, std::string*, std::string*)); MOCK_METHOD2(Unprovision, CdmResponseType(CdmSecurityLevel, - const std::string&)); + const CdmIdentifier&)); MOCK_METHOD2(GetUsageInfo, CdmResponseType(const std::string&, CdmUsageInfo*)); @@ -142,6 +142,10 @@ CdmResponseType setSessionIdOnMap(Unused, CdmQueryMap* map) { return wvcdm::NO_ERROR; } +MATCHER_P(HasOrigin, origin, "") { + return arg.origin == origin; +} + class WVDrmPluginTest : public Test { protected: static const uint32_t kSessionIdSize = 16; @@ -192,7 +196,7 @@ TEST_F(WVDrmPluginTest, OpensSessions) { WVDrmPlugin plugin(cdm.get(), &crypto); EXPECT_CALL(*cdm, - OpenSession(StrEq("com.widevine"), _, StrEq(EMPTY_ORIGIN), _, _)) + OpenSession(StrEq("com.widevine"), _, HasOrigin(EMPTY_ORIGIN), _, _)) .WillOnce(DoAll(SetArgPointee<4>(cdmSessionId), Return(wvcdm::NO_ERROR))); @@ -338,20 +342,23 @@ TEST_F(WVDrmPluginTest, GeneratesKeyRequests) { }; EXPECT_CALL(*cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData, - kLicenseTypeOffline, cdmParameters, _, - _, _)) + kLicenseTypeOffline, cdmParameters, + NotNull(), HasOrigin(EMPTY_ORIGIN), + _)) .WillOnce(DoAll(SetArgPointee<8>(initialRequest), Return(wvcdm::KEY_MESSAGE))); EXPECT_CALL(*cdm, GenerateKeyRequest(cdmSessionId, "", mimeType, initData, kLicenseTypeStreaming, cdmParameters, - _, _, _)) + NotNull(), HasOrigin(EMPTY_ORIGIN), + _)) .WillOnce(DoAll(SetArgPointee<8>(renewalRequest), Return(wvcdm::KEY_MESSAGE))); EXPECT_CALL(*cdm, GenerateKeyRequest("", cdmKeySetId, mimeType, initData, kLicenseTypeRelease, cdmParameters, - NotNull(), StrEq(EMPTY_ORIGIN), _)) + NotNull(), HasOrigin(EMPTY_ORIGIN), + _)) .WillOnce(DoAll(SetArgPointee<8>(releaseRequest), Return(wvcdm::KEY_MESSAGE))); @@ -576,7 +583,7 @@ TEST_F(WVDrmPluginTest, GetsProvisioningRequests) { static const char* kDefaultUrl = "http://google.com/"; EXPECT_CALL(*cdm, GetProvisioningRequest(kCertificateWidevine, IsEmpty(), - EMPTY_ORIGIN, _, _)) + HasOrigin(EMPTY_ORIGIN), _, _)) .WillOnce(DoAll(SetArgPointee<3>(cdmRequest), SetArgPointee<4>(kDefaultUrl), Return(wvcdm::NO_ERROR))); @@ -606,10 +613,10 @@ TEST_F(WVDrmPluginTest, HandlesProvisioningResponses) { Vector response; response.appendArray(responseRaw, kResponseSize); - EXPECT_CALL(*cdm, HandleProvisioningResponse(EMPTY_ORIGIN, - ElementsAreArray(responseRaw, - kResponseSize), - _, _)) + EXPECT_CALL(*cdm, HandleProvisioningResponse(HasOrigin(EMPTY_ORIGIN), + ElementsAreArray(responseRaw, + kResponseSize), + _, _)) .Times(1); Vector cert; @@ -625,9 +632,9 @@ TEST_F(WVDrmPluginTest, UnprovisionsDevice) { StrictMock crypto; WVDrmPlugin plugin(cdm.get(), &crypto); - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, EMPTY_ORIGIN)) + EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, HasOrigin(EMPTY_ORIGIN))) .Times(1); - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, EMPTY_ORIGIN)) + EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(EMPTY_ORIGIN))) .Times(1); status_t res = plugin.unprovisionDevice(); @@ -641,11 +648,11 @@ TEST_F(WVDrmPluginTest, MuxesUnprovisioningErrors) { // Tests that both Unprovisions are called even if one fails. Also tests that // no matter which fails, the function always propagates the error. - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, EMPTY_ORIGIN)) + EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, HasOrigin(EMPTY_ORIGIN))) .WillOnce(Return(wvcdm::UNKNOWN_ERROR)) .WillOnce(Return(wvcdm::NO_ERROR)) .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, EMPTY_ORIGIN)) + EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(EMPTY_ORIGIN))) .WillOnce(Return(wvcdm::NO_ERROR)) .WillOnce(Return(wvcdm::UNKNOWN_ERROR)) .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); @@ -668,9 +675,9 @@ TEST_F(WVDrmPluginTest, UnprovisionsOrigin) { Vector specialResponse; specialResponse.appendArray(kUnprovisionResponse, kUnprovisionResponseSize); - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, StrEq(kOrigin.string()))) + EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, HasOrigin(kOrigin.string()))) .Times(1); - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, StrEq(kOrigin.string()))) + EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(kOrigin.string()))) .Times(1); status_t res = plugin.setPropertyString(String8("origin"), kOrigin); @@ -708,11 +715,11 @@ TEST_F(WVDrmPluginTest, MuxesOriginUnprovisioningErrors) { // Tests that both Unprovisions are called even if one fails. Also tests that // no matter which fails, the function always propagates the error. - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, StrEq(kOrigin.string()))) + EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL1, HasOrigin(kOrigin.string()))) .WillOnce(Return(wvcdm::UNKNOWN_ERROR)) .WillOnce(Return(wvcdm::NO_ERROR)) .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); - EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, StrEq(kOrigin.string()))) + EXPECT_CALL(*cdm, Unprovision(kSecurityLevelL3, HasOrigin(kOrigin.string()))) .WillOnce(Return(wvcdm::NO_ERROR)) .WillOnce(Return(wvcdm::UNKNOWN_ERROR)) .WillOnce(Return(wvcdm::UNKNOWN_ERROR)); @@ -1544,7 +1551,7 @@ TEST_P(WVDrmPluginOriginTest, CanSetOrigin) { } // Note which mock calls we expect - EXPECT_CALL(*cdm, OpenSession(_, _, StrEq(params.expectedOrigin), _, _)) + EXPECT_CALL(*cdm, OpenSession(_, _, HasOrigin(params.expectedOrigin), _, _)) .WillOnce(DoAll(SetArgPointee<4>(cdmSessionId), Return(wvcdm::NO_ERROR)));