diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index 96095c87..aa4900f7 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -65,6 +65,10 @@ class CdmEngine : public TimerHandler { // Query system information virtual CdmResponseType QueryStatus(CdmQueryMap* info); + // Query session information + virtual CdmResponseType QuerySessionStatus(const CdmSessionId& session_id, + CdmQueryMap* key_info); + // Query license information virtual CdmResponseType QueryKeyStatus(const CdmSessionId& session_id, CdmQueryMap* key_info); diff --git a/libwvdrmengine/cdm/core/include/cdm_session.h b/libwvdrmengine/cdm/core/include/cdm_session.h index e6f2bd6e..6cc5920d 100644 --- a/libwvdrmengine/cdm/core/include/cdm_session.h +++ b/libwvdrmengine/cdm/core/include/cdm_session.h @@ -49,6 +49,9 @@ class CdmSession { // CancelKeyRequest() - Cancel session. CdmResponseType CancelKeyRequest(); + // Query session status + CdmResponseType QueryStatus(CdmQueryMap* key_info); + // Query license information CdmResponseType QueryKeyStatus(CdmQueryMap* key_info); diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 76543e34..ff1efe1f 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -401,6 +401,18 @@ CdmResponseType CdmEngine::QueryStatus(CdmQueryMap* key_info) { return NO_ERROR; } +CdmResponseType CdmEngine::QuerySessionStatus(const CdmSessionId& session_id, + CdmQueryMap* key_info) { + LOGI("CdmEngine::QuerySessionStatus"); + CdmSessionMap::iterator iter = sessions_.find(session_id); + if (iter == sessions_.end()) { + LOGE("CdmEngine::QuerySessionStatus: session_id not found = %s", + session_id.c_str()); + return KEY_ERROR; + } + return iter->second->QueryStatus(key_info); +} + CdmResponseType CdmEngine::QueryKeyStatus( const CdmSessionId& session_id, CdmQueryMap* key_info) { diff --git a/libwvdrmengine/cdm/core/src/cdm_session.cpp b/libwvdrmengine/cdm/core/src/cdm_session.cpp index 61b254ae..0ea3d00e 100644 --- a/libwvdrmengine/cdm/core/src/cdm_session.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_session.cpp @@ -239,6 +239,37 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response, } } +CdmResponseType CdmSession::QueryStatus(CdmQueryMap* key_info) { + if (crypto_session_.get() == NULL) { + LOGW("CdmSession::QueryStatus: Invalid crypto session"); + return UNKNOWN_ERROR; + } + + if (!crypto_session_->IsOpen()) { + LOGW("CdmSession::QueryStatus: Crypto session not open"); + return UNKNOWN_ERROR; + } + + switch (crypto_session_->GetSecurityLevel()) { + case kSecurityLevelL1: + (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L1; + break; + case kSecurityLevelL2: + (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L2; + break; + case kSecurityLevelL3: + (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L3; + break; + case kSecurityLevelUninitialized: + case kSecurityLevelUnknown: + (*key_info)[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_Unknown; + break; + default: + return KEY_ERROR; + } + return NO_ERROR; +} + CdmResponseType CdmSession::QueryKeyStatus(CdmQueryMap* key_info) { return policy_engine_.Query(key_info); } diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 0613e507..8e3ccf40 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -49,6 +49,10 @@ class WvContentDecryptionModule { // Query system information virtual CdmResponseType QueryStatus(CdmQueryMap* key_info); + // Query session information + virtual CdmResponseType QuerySessionStatus(const CdmSessionId& session_id, + CdmQueryMap* key_info); + // Query license information virtual CdmResponseType QueryKeyStatus(const CdmSessionId& session_id, CdmQueryMap* key_info); diff --git a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp index bb8bfae1..002646a8 100644 --- a/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp +++ b/libwvdrmengine/cdm/src/wv_content_decryption_module.cpp @@ -85,6 +85,11 @@ CdmResponseType WvContentDecryptionModule::QueryStatus(CdmQueryMap* key_info) { return cdm_engine_->QueryStatus(key_info); } +CdmResponseType WvContentDecryptionModule::QuerySessionStatus( + const CdmSessionId& session_id, CdmQueryMap* key_info) { + return cdm_engine_->QuerySessionStatus(session_id, key_info); +} + CdmResponseType WvContentDecryptionModule::QueryKeyStatus( const CdmSessionId& session_id, CdmQueryMap* key_info) { return cdm_engine_->QueryKeyStatus(session_id, key_info); diff --git a/libwvdrmengine/cdm/test/request_license_test.cpp b/libwvdrmengine/cdm/test/request_license_test.cpp index e2ac4aed..d5a4cc73 100644 --- a/libwvdrmengine/cdm/test/request_license_test.cpp +++ b/libwvdrmengine/cdm/test/request_license_test.cpp @@ -715,6 +715,40 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) { decryptor_.CloseSession(session_id_); } +TEST_F(WvCdmRequestLicenseTest, QuerySessionStatus) { + // Test that the global value is returned when no properties are modifying it. + CdmQueryMap system_query_info; + CdmQueryMap::iterator system_itr; + ASSERT_EQ(wvcdm::NO_ERROR, decryptor_.QueryStatus(&system_query_info)); + system_itr = system_query_info.find(wvcdm::QUERY_KEY_SECURITY_LEVEL); + ASSERT_TRUE(system_itr != system_query_info.end()); + + decryptor_.OpenSession(g_key_system, NULL, &session_id_); + CdmQueryMap unmodified_query_info; + CdmQueryMap::iterator unmodified_itr; + ASSERT_EQ(wvcdm::NO_ERROR, + decryptor_.QuerySessionStatus(session_id_, &unmodified_query_info)); + unmodified_itr = unmodified_query_info.find(wvcdm::QUERY_KEY_SECURITY_LEVEL); + ASSERT_TRUE(unmodified_itr != unmodified_query_info.end()); + EXPECT_EQ(system_itr->second, unmodified_itr->second); + decryptor_.CloseSession(session_id_); + + // Test that L3 is returned when properties downgrade security. + TestWvCdmClientPropertySet property_set_L3; + property_set_L3.set_security_level(QUERY_VALUE_SECURITY_LEVEL_L3); + + decryptor_.OpenSession(g_key_system, &property_set_L3, &session_id_); + CdmQueryMap modified_query_info; + CdmQueryMap::iterator modified_itr; + ASSERT_EQ(wvcdm::NO_ERROR, + decryptor_.QuerySessionStatus(session_id_, &modified_query_info)); + modified_itr = modified_query_info.find(wvcdm::QUERY_KEY_SECURITY_LEVEL); + ASSERT_TRUE(modified_itr != modified_query_info.end()); + EXPECT_EQ(QUERY_VALUE_SECURITY_LEVEL_L3, modified_itr->second); + decryptor_.CloseSession(session_id_); + +} + TEST_F(WvCdmRequestLicenseTest, QueryKeyStatus) { decryptor_.OpenSession(g_key_system, NULL, &session_id_); GenerateKeyRequest(g_key_system, g_key_id, kLicenseTypeStreaming); diff --git a/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp b/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp index 63e3c647..812f98c8 100644 --- a/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp +++ b/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp @@ -50,7 +50,7 @@ bool WVCryptoPlugin::requiresSecureDecoderComponent(const char* mime) const { // Type is video, so query CDM to see if we require a secure decoder. CdmQueryMap status; - CdmResponseType res = mCDM->QueryStatus(&status); + CdmResponseType res = mCDM->QuerySessionStatus(mSessionId, &status); if (!isCdmResponseTypeSuccess(res)) { ALOGE("Error querying CDM status: %u", res); diff --git a/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp b/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp index 344ac5f6..ca188926 100644 --- a/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp +++ b/libwvdrmengine/mediacrypto/test/WVCryptoPlugin_test.cpp @@ -27,7 +27,8 @@ class MockCDM : public WvContentDecryptionModule { MOCK_METHOD2(Decrypt, CdmResponseType(const CdmSessionId&, const CdmDecryptionParameters&)); - MOCK_METHOD1(QueryStatus, CdmResponseType(CdmQueryMap*)); + MOCK_METHOD2(QuerySessionStatus, CdmResponseType(const CdmSessionId&, + CdmQueryMap*)); }; class WVCryptoPluginTest : public Test { @@ -55,10 +56,10 @@ TEST_F(WVCryptoPluginTest, CorrectlyReportsSecureBuffers) { CdmQueryMap l3Map; l3Map[QUERY_KEY_SECURITY_LEVEL] = QUERY_VALUE_SECURITY_LEVEL_L3; - EXPECT_CALL(cdm, QueryStatus(_)) - .WillOnce(DoAll(SetArgPointee<0>(l1Map), + EXPECT_CALL(cdm, QuerySessionStatus(_, _)) + .WillOnce(DoAll(SetArgPointee<1>(l1Map), Return(wvcdm::NO_ERROR))) - .WillOnce(DoAll(SetArgPointee<0>(l3Map), + .WillOnce(DoAll(SetArgPointee<1>(l3Map), Return(wvcdm::NO_ERROR))); EXPECT_TRUE(plugin.requiresSecureDecoderComponent("video/mp4")) <<