From 23c95a12511b3d538cbd5d0ce4698901e7aae416 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Thu, 19 Feb 2015 16:52:23 -0800 Subject: [PATCH] Merge MaxNumberOfSessions changes from CDM Bug: 18377675 Implement new OEMCrypto function to get max number of sessions https://widevine-internal-review.googlesource.com/#/c/12980/ Add oemcrypto static adapter for v9 https://widevine-internal-review.googlesource.com/#/c/13022/ Support new property to query MaxNumberOfSessions in CDM https://widevine-internal-review.googlesource.com/#/c/13020/ Fix GetHdcpCapabilities incorrect return if not initialized https://widevine-internal-review.googlesource.com/#/c/13210/ Change-Id: I02738c543cedd6e38d8826f845fec6cb2b1ede3c --- .../cdm/core/include/crypto_session.h | 1 + .../cdm/core/include/wv_cdm_constants.h | 1 + libwvdrmengine/cdm/core/src/cdm_engine.cpp | 6 + .../cdm/core/src/crypto_session.cpp | 26 ++- .../core/src/oemcrypto_adapter_dynamic.cpp | 159 ++++++++++-------- libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp | 11 ++ .../mediadrm/test/WVDrmPlugin_test.cpp | 10 ++ .../oemcrypto/include/OEMCryptoCENC.h | 25 +++ libwvdrmengine/oemcrypto/include/level3.h | 2 + .../oemcrypto/mock/src/oemcrypto_mock.cpp | 11 ++ .../oemcrypto/test/oemcrypto_test.cpp | 21 ++- 11 files changed, 199 insertions(+), 74 deletions(-) diff --git a/libwvdrmengine/cdm/core/include/crypto_session.h b/libwvdrmengine/cdm/core/include/crypto_session.h index 147df355..25f85ee6 100644 --- a/libwvdrmengine/cdm/core/include/crypto_session.h +++ b/libwvdrmengine/cdm/core/include/crypto_session.h @@ -101,6 +101,7 @@ class CryptoSession { virtual bool GetHdcpCapabilities(OemCryptoHdcpVersion* current, OemCryptoHdcpVersion* max); virtual bool GetRandom(size_t data_length, uint8_t* random_data); + virtual bool GetMaxNumberOfSessions(size_t* max); private: void Init(); diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h index 0c67de5f..fd5fbda4 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h @@ -49,6 +49,7 @@ static const std::string QUERY_KEY_MAX_HDCP_LEVEL = "MaxHdcpLevel"; // maximum supported HDCP level static const std::string QUERY_KEY_USAGE_SUPPORT = "UsageSupport"; // whether usage reporting is supported +static const std::string QUERY_KEY_MAX_NUMBER_OF_SESSIONS = "MaxNumberOfSessions"; static const std::string QUERY_VALUE_TRUE = "True"; static const std::string QUERY_VALUE_FALSE = "False"; diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 8b497110..b8b82784 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -449,6 +449,12 @@ CdmResponseType CdmEngine::QueryStatus(CdmQueryMap* key_info) { supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; } + size_t maximum_number_of_sessions; + success = crypto_session.GetMaxNumberOfSessions(&maximum_number_of_sessions); + if (success) { + (*key_info)[QUERY_KEY_MAX_NUMBER_OF_SESSIONS] = maximum_number_of_sessions; + } + return NO_ERROR; } diff --git a/libwvdrmengine/cdm/core/src/crypto_session.cpp b/libwvdrmengine/cdm/core/src/crypto_session.cpp index 3c4c2ec6..010b270c 100644 --- a/libwvdrmengine/cdm/core/src/crypto_session.cpp +++ b/libwvdrmengine/cdm/core/src/crypto_session.cpp @@ -951,7 +951,13 @@ bool CryptoSession::RewrapDeviceRSAKey(const std::string& message, bool CryptoSession::GetHdcpCapabilities(OemCryptoHdcpVersion* current_version, OemCryptoHdcpVersion* max_version) { LOGV("GetHdcpCapabilities: id=%ld", (uint32_t)oec_session_id_); - if (!initialized_) return UNKNOWN_ERROR; + if (!initialized_) return false; + if (current_version == NULL || max_version == NULL) { + LOGE( + "CryptoSession::GetHdcpCapabilities: |current_version|, " + "|max_version| cannot be NULL"); + return false; + } OEMCrypto_HDCP_Capability current, max; OEMCryptoResult status = OEMCrypto_GetHDCPCapability(¤t, &max); @@ -980,4 +986,22 @@ bool CryptoSession::GetRandom(size_t data_length, uint8_t* random_data) { return true; } +bool CryptoSession::GetMaxNumberOfSessions(size_t* max) { + LOGV("GetMaxNumberOfSessions"); + if (!initialized_) return false; + if (max == NULL) { + LOGE("CryptoSession::GetMaxNumberOfSessions: |max| cannot be NULL"); + return false; + } + + size_t max_sessions; + OEMCryptoResult status = OEMCrypto_GetMaxNumberOfSessions(&max_sessions); + if (OEMCrypto_SUCCESS != status) { + LOGW("OEMCrypto_GetMaxNumberOfSessions fails with %d", status); + return false; + } + *max = max_sessions; + return true; +} + }; // namespace wvcdm diff --git a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp index 61d6b0e7..90c038c9 100644 --- a/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp +++ b/libwvdrmengine/cdm/core/src/oemcrypto_adapter_dynamic.cpp @@ -24,8 +24,10 @@ #include "properties.h" using namespace wvoec3; +using wvcdm::kLevelDefault; +using wvcdm::kLevel3; -namespace wvcdm { +namespace { typedef OEMCryptoResult (*L1_Initialize_t)(void); typedef OEMCryptoResult (*L1_Terminate_t)(void); @@ -138,6 +140,7 @@ typedef OEMCryptoResult (*L1_DeleteUsageEntry_t)( const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length); typedef OEMCryptoResult (*L1_DeleteUsageTable_t)(); +typedef OEMCryptoResult (*L1_GetMaxNumberOfSessions_t)(size_t *maximum); struct FunctionPointers { uint32_t version; @@ -175,6 +178,7 @@ struct FunctionPointers { L1_ReportUsage_t ReportUsage; L1_DeleteUsageEntry_t DeleteUsageEntry; L1_DeleteUsageTable_t DeleteUsageTable; + L1_GetMaxNumberOfSessions_t GetMaxNumberOfSessions; L1_LoadKeys_V8_t LoadKeys_V8; L1_GenerateRSASignature_V8_t GenerateRSASignature_V8; @@ -290,6 +294,9 @@ class Adapter { LOOKUP(DeleteUsageEntry, OEMCrypto_DeleteUsageEntry); LOOKUP(DeleteUsageTable, OEMCrypto_DeleteUsageTable); } + if (level1_.version >= 10) { + LOOKUP(GetMaxNumberOfSessions, OEMCrypto_GetMaxNumberOfSessions); + } if (OEMCrypto_SUCCESS == level1_.IsKeyboxValid()) { return true; } @@ -353,6 +360,7 @@ class Adapter { level3_.ReportUsage = Level3_ReportUsage; level3_.DeleteUsageEntry = Level3_DeleteUsageEntry; level3_.DeleteUsageTable = Level3_DeleteUsageTable; + level3_.GetMaxNumberOfSessions = Level3_GetMaxNumberOfSessions; level3_.version = Level3_APIVersion(); } @@ -366,13 +374,13 @@ class Adapter { return result; } - const FunctionPointers* get(SecurityLevel level) { + const FunctionPointers* get(wvcdm::SecurityLevel level) { if (level1_valid_ && level == kLevelDefault) return &level1_; return &level3_; } LevelSession get(OEMCrypto_SESSION session) { - AutoLock auto_lock(session_map_lock_); + wvcdm::AutoLock auto_lock(session_map_lock_); map_iterator pair = session_map_.find(session); if (pair == session_map_.end()) { return LevelSession(); @@ -380,7 +388,8 @@ class Adapter { return pair->second; } - OEMCryptoResult OpenSession(OEMCrypto_SESSION* session, SecurityLevel level) { + OEMCryptoResult OpenSession(OEMCrypto_SESSION* session, + wvcdm::SecurityLevel level) { LevelSession new_session; OEMCryptoResult result; if (level == kLevelDefault && level1_valid_) { @@ -393,7 +402,7 @@ class Adapter { *session = new_session.session + kLevel3Offset; } if (result == OEMCrypto_SUCCESS) { - AutoLock auto_lock(session_map_lock_); + wvcdm::AutoLock auto_lock(session_map_lock_); // Make sure session is not already in my list of sessions. while (session_map_.find(*session) != session_map_.end()) { (*session)++; @@ -404,7 +413,7 @@ class Adapter { } OEMCryptoResult CloseSession(OEMCrypto_SESSION session) { - AutoLock auto_lock(session_map_lock_); + wvcdm::AutoLock auto_lock(session_map_lock_); map_iterator pair = session_map_.find(session); if (pair == session_map_.end()) { return OEMCrypto_ERROR_INVALID_SESSION; @@ -421,7 +430,7 @@ class Adapter { struct FunctionPointers level1_; struct FunctionPointers level3_; std::map session_map_; - Lock session_map_lock_; + wvcdm::Lock session_map_lock_; // This is just for debugging the map between session ids. // If we add this to the level 3 session id, then the external session // id will match the internal session id in the last two digits. @@ -430,6 +439,72 @@ class Adapter { static Adapter* kAdapter = 0; +} // namespace + +namespace wvcdm { + +OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session, + SecurityLevel level) { + if (!kAdapter) return OEMCrypto_ERROR_OPEN_SESSION_FAILED; + return kAdapter->OpenSession(session, level); +} + +OEMCryptoResult OEMCrypto_IsKeyboxValid(SecurityLevel level) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; + return fcn->IsKeyboxValid(); +} + +OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength, + SecurityLevel level) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; + return fcn->GetDeviceID(deviceID, idLength); +} + +OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength, + SecurityLevel level) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; + return fcn->GetKeyData(keyData, keyDataLength); +} + +OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox, + size_t keyBoxLength, + SecurityLevel level) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; + return fcn->InstallKeybox(keybox, keyBoxLength); +} + +uint32_t OEMCrypto_APIVersion(SecurityLevel level) { + if (!kAdapter) return 0; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return 0; + return fcn->APIVersion(); +} + +const char* OEMCrypto_SecurityLevel(SecurityLevel level) { + if (!kAdapter) return ""; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return ""; + return fcn->SecurityLevel(); +} + +bool OEMCrypto_SupportsUsageTable(SecurityLevel level) { + if (!kAdapter) return false; + const FunctionPointers* fcn = kAdapter->get(level); + if (!fcn) return false; + if (fcn->version == 8) return false; + return fcn->SupportsUsageTable(); +} + +}; // namespace wvcdm + extern "C" OEMCryptoResult OEMCrypto_Initialize(void) { if (kAdapter) { delete kAdapter; @@ -452,12 +527,6 @@ extern "C" OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session) { return OEMCrypto_OpenSession(session, kLevelDefault); } -OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION* session, - SecurityLevel level) { - if (!kAdapter) return OEMCrypto_ERROR_OPEN_SESSION_FAILED; - return kAdapter->OpenSession(session, level); -} - extern "C" OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) { if (!kAdapter) return OEMCrypto_ERROR_CLOSE_SESSION_FAILED; return kAdapter->CloseSession(session); @@ -550,52 +619,20 @@ extern "C" OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox, return OEMCrypto_InstallKeybox(keybox, keyBoxLength, kLevelDefault); } -OEMCryptoResult OEMCrypto_InstallKeybox(const uint8_t* keybox, - size_t keyBoxLength, - SecurityLevel level) { - if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - const FunctionPointers* fcn = kAdapter->get(level); - if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; - return fcn->InstallKeybox(keybox, keyBoxLength); -} - extern "C" OEMCryptoResult OEMCrypto_IsKeyboxValid() { return OEMCrypto_IsKeyboxValid(kLevelDefault); } -OEMCryptoResult OEMCrypto_IsKeyboxValid(SecurityLevel level) { - if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - const FunctionPointers* fcn = kAdapter->get(level); - if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; - return fcn->IsKeyboxValid(); -} - extern "C" OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength) { return OEMCrypto_GetDeviceID(deviceID, idLength, kLevelDefault); } -OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID, size_t* idLength, - SecurityLevel level) { - if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - const FunctionPointers* fcn = kAdapter->get(level); - if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; - return fcn->GetDeviceID(deviceID, idLength); -} - extern "C" OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength) { return OEMCrypto_GetKeyData(keyData, keyDataLength, kLevelDefault); } -OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData, size_t* keyDataLength, - SecurityLevel level) { - if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; - const FunctionPointers* fcn = kAdapter->get(level); - if (!fcn) return OEMCrypto_ERROR_INVALID_SESSION; - return fcn->GetKeyData(keyData, keyDataLength); -} - extern "C" OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData, size_t dataLength) { if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; @@ -676,24 +713,10 @@ extern "C" uint32_t OEMCrypto_APIVersion() { return OEMCrypto_APIVersion(kLevelDefault); } -uint32_t OEMCrypto_APIVersion(SecurityLevel level) { - if (!kAdapter) return 0; - const FunctionPointers* fcn = kAdapter->get(level); - if (!fcn) return 0; - return fcn->APIVersion(); -} - extern "C" const char* OEMCrypto_SecurityLevel() { return OEMCrypto_SecurityLevel(kLevelDefault); } -const char* OEMCrypto_SecurityLevel(SecurityLevel level) { - if (!kAdapter) return ""; - const FunctionPointers* fcn = kAdapter->get(level); - if (!fcn) return ""; - return fcn->SecurityLevel(); -} - extern "C" OEMCryptoResult OEMCrypto_Generic_Encrypt( OEMCrypto_SESSION session, const uint8_t* in_buffer, size_t buffer_length, const uint8_t* iv, OEMCrypto_Algorithm algorithm, uint8_t* out_buffer) { @@ -751,14 +774,6 @@ extern "C" bool OEMCrypto_SupportsUsageTable() { return OEMCrypto_SupportsUsageTable(kLevelDefault); } -bool OEMCrypto_SupportsUsageTable(SecurityLevel level) { - if (!kAdapter) return false; - const FunctionPointers* fcn = kAdapter->get(level); - if (!fcn) return false; - if( fcn->version == 8 ) return false; - return fcn->SupportsUsageTable(); -} - extern "C" OEMCryptoResult OEMCrypto_UpdateUsageTable() { if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; const FunctionPointers* fcn1 = kAdapter->get(kLevelDefault); @@ -828,4 +843,12 @@ extern "C" OEMCryptoResult OEMCrypto_DeleteUsageTable() { return sts; } -}; // namespace wvcdm +extern "C" OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *maximum) { + if (!kAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const FunctionPointers* fcn = kAdapter->get(kLevelDefault); + if (!fcn) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + if (fcn->version < 10) { + return OEMCrypto_ERROR_NOT_IMPLEMENTED; + } + return fcn->GetMaxNumberOfSessions(maximum); +} diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index e318650f..c6f56c2d 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -529,6 +529,17 @@ status_t WVDrmPlugin::getPropertyString(const String8& name, return kErrorCDMGeneric; } value = status[QUERY_KEY_USAGE_SUPPORT].c_str(); + } else if (name == "maxNumberOfSessions") { + CdmQueryMap status; + CdmResponseType res = mCDM->QueryStatus(&status); + if (res != wvcdm::NO_ERROR) { + ALOGE("Error querying CDM status: %u", res); + return mapCdmResponseType(res); + } else if (!status.count(QUERY_KEY_MAX_NUMBER_OF_SESSIONS)) { + ALOGE("CDM did not report maximum number of media drm sessions"); + return kErrorCDMGeneric; + } + value = status[QUERY_KEY_MAX_NUMBER_OF_SESSIONS].c_str(); } else { ALOGE("App requested unknown string property %s", name.string()); return android::ERROR_DRM_CANNOT_HANDLE; diff --git a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp index d1400494..1539e96a 100644 --- a/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp +++ b/libwvdrmengine/mediadrm/test/WVDrmPlugin_test.cpp @@ -708,6 +708,10 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { CdmQueryMap provisioningIDMap; provisioningIDMap[QUERY_KEY_PROVISIONING_ID] = provisioningId; + static const string maxSessions = "18"; + CdmQueryMap maxSessionsMap; + maxSessionsMap[QUERY_KEY_MAX_NUMBER_OF_SESSIONS] = maxSessions; + EXPECT_CALL(cdm, QueryStatus(_)) .WillOnce(DoAll(SetArgPointee<0>(l1Map), Return(wvcdm::NO_ERROR))) @@ -718,6 +722,8 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { .WillOnce(DoAll(SetArgPointee<0>(systemIDMap), Return(wvcdm::NO_ERROR))) .WillOnce(DoAll(SetArgPointee<0>(provisioningIDMap), + Return(wvcdm::NO_ERROR))) + .WillOnce(DoAll(SetArgPointee<0>(maxSessionsMap), Return(wvcdm::NO_ERROR))); String8 stringResult; @@ -759,6 +765,10 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) { ASSERT_EQ(OK, res); EXPECT_THAT(vectorResult, ElementsAreArray(provisioningId.data(), provisioningId.size())); + + res = plugin.getPropertyString(String8("maxNumberOfSessions"), stringResult); + ASSERT_EQ(OK, res); + EXPECT_EQ(maxSessions, stringResult.string()); } TEST_F(WVDrmPluginTest, DoesNotGetUnknownProperties) { diff --git a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h index 9998c978..f55a3c6f 100644 --- a/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h +++ b/libwvdrmengine/oemcrypto/include/OEMCryptoCENC.h @@ -274,6 +274,7 @@ typedef enum RSA_Padding_Scheme { #define OEMCrypto_DeleteUsageTable _oecc34 #define OEMCrypto_LoadKeys _oecc35 #define OEMCrypto_GenerateRSASignature _oecc36 +#define OEMCrypto_GetMaxNumberOfSessions _oecc37 /* * OEMCrypto_Initialize @@ -1993,6 +1994,30 @@ OEMCryptoResult OEMCrypto_DeleteUsageEntry(OEMCrypto_SESSION session, */ OEMCryptoResult OEMCrypto_DeleteUsageTable(); +/* + * OEMCRYPTO_GetMaxNumberOfSessions() + * + * Description: + * Returns the maximum number of concurrent OEMCrypto sessions supported by + * the device. The CDM and OEMCrypto consumers can query this value so they + * can use resources more effectively. + * + * Parameters: + * maximum (out) - the maximum number of OEMCrypto sessions supported by the + * device. + * + * Threading: + * This function may be called simultaneously with any other functions. + * + * Returns: + * OEMCrypto_SUCCESS + * OEMCrypto_ERROR_UNKNOWN_FAILURE + * + * Version: + * This method is added in API version 10. + */ +OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *max); + #ifdef __cplusplus } #endif diff --git a/libwvdrmengine/oemcrypto/include/level3.h b/libwvdrmengine/oemcrypto/include/level3.h index c9a4fd85..11b779f9 100644 --- a/libwvdrmengine/oemcrypto/include/level3.h +++ b/libwvdrmengine/oemcrypto/include/level3.h @@ -50,6 +50,7 @@ namespace wvoec3 { #define Level3_ReportUsage _lcc32 #define Level3_DeleteUsageEntry _lcc33 #define Level3_DeleteUsageTable _lcc34 +#define Level3_GetMaxNumberOfSessions _lcc37 extern "C" { @@ -185,6 +186,7 @@ OEMCryptoResult Level3_DeleteUsageEntry(OEMCrypto_SESSION session, const uint8_t *signature, size_t signature_length); OEMCryptoResult Level3_DeleteUsageTable(); +OEMCryptoResult Level3_GetMaxNumberOfSessions(size_t *maximum); }; } #endif // LEVEL3_OEMCRYPTO_H_ diff --git a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp index af70498d..626c1cdf 100644 --- a/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp +++ b/libwvdrmengine/oemcrypto/mock/src/oemcrypto_mock.cpp @@ -1291,4 +1291,15 @@ OEMCryptoResult OEMCrypto_DeleteUsageTable() { return OEMCrypto_SUCCESS; } +extern "C" +OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(size_t *maximum) { + if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { + LOGI("-- OEMCryptoResult OEMCrypto_GetMaxNumberOfSessions(%p)\n", maximum); + } + if (maximum == NULL) return OEMCrypto_ERROR_UNKNOWN_FAILURE; + const size_t kMaxSupportedOEMCryptoSessions = 64; + *maximum = kMaxSupportedOEMCryptoSessions; + return OEMCrypto_SUCCESS; +} + } // namespace wvoec_mock diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index c99a8f4e..81b01775 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -1597,7 +1597,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) { uint32_t version = OEMCrypto_APIVersion(); cout << " OEMCrypto API version is " << version << endl; ASSERT_LE(8, version); - ASSERT_GE(9, version); + ASSERT_GE(10, version); } TEST_F(OEMCryptoClientTest, NormalGetKeyData) { @@ -1650,6 +1650,13 @@ TEST_F(OEMCryptoClientTest, CheckHDCPCapability) { HDCPCapabilityAsString(maximum)); } +TEST_F(OEMCryptoClientTest, CheckMaxNumberOfOEMCryptoSessions) { + size_t maximum; + OEMCryptoResult sts = OEMCrypto_GetMaxNumberOfSessions(&maximum); + ASSERT_EQ(OEMCrypto_SUCCESS, sts); + printf(" Max Number of Sessions: %zu.\n", maximum); +} + TEST_F(OEMCryptoClientTest, KeyboxValid) { ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_IsKeyboxValid()); } @@ -1732,19 +1739,23 @@ TEST_F(OEMCryptoClientTest, TwoSessionsOpenClose) { ASSERT_FALSE(s2.isOpen()); } -TEST_F(OEMCryptoClientTest, EightSessionsOpenClose) { - Session s[8]; - for (int i = 0; i < 8; i++) { +TEST_F(OEMCryptoClientTest, MaxSessionsOpenClose) { + size_t max_sessions; + ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_GetMaxNumberOfSessions(&max_sessions)); + ASSERT_GT(max_sessions, 0); + vector s(max_sessions); + for (int i = 0; i < s.size(); i++) { s[i].open(); ASSERT_EQ(OEMCrypto_SUCCESS, s[i].getStatus()); ASSERT_TRUE(s[i].isOpen()); } - for (int i = 0; i < 8; i++) { + for (int i = 0; i < s.size(); i++) { s[i].close(); ASSERT_EQ(OEMCrypto_SUCCESS, s[i].getStatus()); ASSERT_FALSE(s[i].isOpen()); } } +// TODO(kqyang): Add more tests exercising multiple sessions. TEST_F(OEMCryptoClientTest, GenerateNonce) { Session s;