L1 System Lowered to L3 Still Requires Secure Decoders
Merge of https://widevine-internal-review.googlesource.com/#/c/8263 from the Widevine repo. Changes the behavior of requiresSecureDecoderComponent() to query the session for whether a lowered security level has been requested before querying the system to see what its default security level is. As part of this, we added a new QuerySessionStatus() method to the CDM that gets status info on a session-specific level, such as the effective security level of a session. Bug: 11428937 Change-Id: I5549a2fdd400cc87f567d27fcf74c473451093d6
This commit is contained in:
committed by
John Bruce
parent
0a9f0b1dd8
commit
fd482527e4
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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")) <<
|
||||
|
||||
Reference in New Issue
Block a user