Improve query performance

[ Merge of http://go/wvgerrit/15780 ]

Android mediaDrm allows callers to serially query status information through a
property API. CDM however retrieves all status information in a map and
filters out all but the relevent one. This leads to delays in Netflix app
startup. Rewriting the CDM interface to return only the queried value.

b/24181894

Change-Id: Ie9ed6288524e3a7e03b83aa55ef3531dd52a0dfb
This commit is contained in:
Rahul Frias
2015-10-05 15:22:20 -07:00
parent dfe644da56
commit e5dfb83e03
7 changed files with 270 additions and 217 deletions

View File

@@ -2051,14 +2051,12 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) {
TEST_F(WvCdmRequestLicenseTest, QueryUnmodifiedSessionStatus) {
// Test that the global value is returned when no properties are modifying it.
CdmQueryMap system_query_info;
CdmQueryMap::iterator system_itr;
std::string security_level;
ASSERT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault, &system_query_info));
system_itr = system_query_info.find(wvcdm::QUERY_KEY_SECURITY_LEVEL);
ASSERT_TRUE(system_itr != system_query_info.end());
EXPECT_EQ(system_itr->second, GetSecurityLevel(NULL));
decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_SECURITY_LEVEL,
&security_level));
EXPECT_EQ(GetSecurityLevel(NULL), security_level);
}
TEST_F(WvCdmRequestLicenseTest, QueryModifiedSessionStatus) {
@@ -2121,68 +2119,72 @@ TEST_F(WvCdmRequestLicenseTest, QueryKeyStatus) {
}
TEST_F(WvCdmRequestLicenseTest, QueryStatus) {
CdmQueryMap query_info;
CdmQueryMap::iterator itr;
std::string value;
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault, &query_info));
decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_SECURITY_LEVEL, &value));
itr = query_info.find(wvcdm::QUERY_KEY_SECURITY_LEVEL);
ASSERT_TRUE(itr != query_info.end());
EXPECT_EQ(2u, itr->second.size());
EXPECT_EQ(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3.at(0), itr->second.at(0));
EXPECT_EQ(2u, value.size());
EXPECT_TRUE(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3 == value ||
wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1 == value);
itr = query_info.find(wvcdm::QUERY_KEY_DEVICE_ID);
ASSERT_TRUE(itr != query_info.end());
EXPECT_GT(itr->second.size(), 0u);
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_DEVICE_ID,
&value));
EXPECT_LT(0u, value.size());
itr = query_info.find(wvcdm::QUERY_KEY_SYSTEM_ID);
ASSERT_TRUE(itr != query_info.end());
std::istringstream ss(itr->second);
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_SYSTEM_ID,
&value));
std::istringstream ss(value);
uint32_t system_id;
ss >> system_id;
ASSERT_FALSE(ss.fail());
EXPECT_TRUE(ss.eof());
itr = query_info.find(wvcdm::QUERY_KEY_PROVISIONING_ID);
ASSERT_TRUE(itr != query_info.end());
EXPECT_EQ(16u, itr->second.size());
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_PROVISIONING_ID, &value));
EXPECT_EQ(16u, value.size());
itr = query_info.find(QUERY_KEY_CURRENT_HDCP_LEVEL);
ASSERT_TRUE(itr != query_info.end());
EXPECT_TRUE(itr->second == QUERY_VALUE_UNPROTECTED ||
itr->second == QUERY_VALUE_HDCP_V1 ||
itr->second == QUERY_VALUE_HDCP_V2_0 ||
itr->second == QUERY_VALUE_HDCP_V2_1 ||
itr->second == QUERY_VALUE_HDCP_V2_2 ||
itr->second == QUERY_VALUE_DISCONNECTED);
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(
kLevelDefault, wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL, &value));
EXPECT_TRUE(
value == QUERY_VALUE_UNPROTECTED || value == QUERY_VALUE_HDCP_V1 ||
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
value == QUERY_VALUE_HDCP_V2_2 || value == QUERY_VALUE_DISCONNECTED);
itr = query_info.find(QUERY_KEY_MAX_HDCP_LEVEL);
ASSERT_TRUE(itr != query_info.end());
EXPECT_TRUE(itr->second == QUERY_VALUE_UNPROTECTED ||
itr->second == QUERY_VALUE_HDCP_V1 ||
itr->second == QUERY_VALUE_HDCP_V2_0 ||
itr->second == QUERY_VALUE_HDCP_V2_1 ||
itr->second == QUERY_VALUE_HDCP_V2_2 ||
itr->second == QUERY_VALUE_DISCONNECTED);
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_MAX_HDCP_LEVEL, &value));
EXPECT_TRUE(
value == QUERY_VALUE_UNPROTECTED || value == QUERY_VALUE_HDCP_V1 ||
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
value == QUERY_VALUE_HDCP_V2_2 || value == QUERY_VALUE_DISCONNECTED);
itr = query_info.find(QUERY_KEY_USAGE_SUPPORT);
ASSERT_TRUE(itr != query_info.end());
EXPECT_TRUE(itr->second == QUERY_VALUE_TRUE ||
itr->second == QUERY_VALUE_FALSE);
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_USAGE_SUPPORT, &value));
EXPECT_TRUE(value == QUERY_VALUE_TRUE || value == QUERY_VALUE_FALSE);
itr = query_info.find(QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
ASSERT_TRUE(itr != query_info.end());
EXPECT_EQ(
wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS, &value));
ss.clear();
ss.str(itr->second);
ss.str(value);
uint32_t open_sessions;
ss >> open_sessions;
ASSERT_FALSE(ss.fail());
EXPECT_TRUE(ss.eof());
itr = query_info.find(QUERY_KEY_MAX_NUMBER_OF_SESSIONS);
ASSERT_TRUE(itr != query_info.end());
EXPECT_EQ(
wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS, &value));
ss.clear();
ss.str(itr->second);
ss.str(value);
uint32_t max_sessions;
ss >> max_sessions;
ASSERT_FALSE(ss.fail());
@@ -2190,10 +2192,11 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatus) {
EXPECT_LE(open_sessions, max_sessions);
EXPECT_LE(8u, max_sessions);
itr = query_info.find(QUERY_KEY_OEMCRYPTO_API_VERSION);
ASSERT_TRUE(itr != query_info.end());
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(
kLevelDefault, wvcdm::QUERY_KEY_OEMCRYPTO_API_VERSION, &value));
ss.clear();
ss.str(itr->second);
ss.str(value);
uint32_t api_version;
ss >> api_version;
ASSERT_FALSE(ss.fail());
@@ -2202,50 +2205,94 @@ TEST_F(WvCdmRequestLicenseTest, QueryStatus) {
}
TEST_F(WvCdmRequestLicenseTest, QueryStatusL3) {
CdmQueryMap query_info, query_info_default;
CdmQueryMap::iterator itr;
std::string value;
EXPECT_EQ(
wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_SECURITY_LEVEL, &value));
EXPECT_EQ(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3, value);
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.QueryStatus(
kLevel3, wvcdm::QUERY_KEY_DEVICE_ID, &value));
EXPECT_LT(0u, value.size());
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevel3, &query_info));
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault, &query_info_default));
decryptor_.QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_SYSTEM_ID,
&value));
std::istringstream ss(value);
uint32_t default_system_id;
ss >> default_system_id;
ASSERT_FALSE(ss.fail());
EXPECT_TRUE(ss.eof());
EXPECT_THAT(query_info, Contains(Pair(wvcdm::QUERY_KEY_SECURITY_LEVEL,
wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3)));
itr = query_info.find(wvcdm::QUERY_KEY_DEVICE_ID);
ASSERT_TRUE(itr != query_info.end());
EXPECT_GT(itr->second.size(), 0u);
itr = query_info.find(wvcdm::QUERY_KEY_SYSTEM_ID);
ASSERT_TRUE(itr != query_info.end());
std::istringstream ss(itr->second);
EXPECT_EQ(wvcdm::NO_ERROR, decryptor_.QueryStatus(
kLevel3, wvcdm::QUERY_KEY_SYSTEM_ID, &value));
ss.clear();
ss.str(value);
uint32_t system_id;
ss >> system_id;
ASSERT_FALSE(ss.fail());
EXPECT_TRUE(ss.eof());
EXPECT_NE(default_system_id, system_id);
itr = query_info.find(wvcdm::QUERY_KEY_PROVISIONING_ID);
ASSERT_TRUE(itr != query_info.end());
EXPECT_EQ(16u, itr->second.size());
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_PROVISIONING_ID,
&value));
EXPECT_EQ(16u, value.size());
itr = query_info_default.find(wvcdm::QUERY_KEY_SECURITY_LEVEL);
ASSERT_TRUE(itr != query_info_default.end());
EXPECT_EQ(2u, itr->second.size());
EXPECT_EQ(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3.at(0), itr->second.at(0));
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_CURRENT_HDCP_LEVEL,
&value));
EXPECT_TRUE(
value == QUERY_VALUE_UNPROTECTED || value == QUERY_VALUE_HDCP_V1 ||
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
value == QUERY_VALUE_HDCP_V2_2 || value == QUERY_VALUE_DISCONNECTED);
if (wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3.compare(itr->second) != 0) {
itr = query_info_default.find(wvcdm::QUERY_KEY_SYSTEM_ID);
ASSERT_TRUE(itr != query_info_default.end());
std::istringstream ss(itr->second);
uint32_t default_system_id;
ss >> system_id;
ASSERT_FALSE(ss.fail());
EXPECT_TRUE(ss.eof());
EXPECT_NE(system_id, default_system_id);
}
EXPECT_EQ(
wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_MAX_HDCP_LEVEL, &value));
EXPECT_TRUE(
value == QUERY_VALUE_UNPROTECTED || value == QUERY_VALUE_HDCP_V1 ||
value == QUERY_VALUE_HDCP_V2_0 || value == QUERY_VALUE_HDCP_V2_1 ||
value == QUERY_VALUE_HDCP_V2_2 || value == QUERY_VALUE_DISCONNECTED);
EXPECT_EQ(
wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevel3, wvcdm::QUERY_KEY_USAGE_SUPPORT, &value));
EXPECT_TRUE(value == QUERY_VALUE_TRUE || value == QUERY_VALUE_FALSE);
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(
kLevel3, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS, &value));
ss.clear();
ss.str(value);
uint32_t open_sessions;
ss >> open_sessions;
ASSERT_FALSE(ss.fail());
EXPECT_TRUE(ss.eof());
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(
kLevel3, wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS, &value));
ss.clear();
ss.str(value);
uint32_t max_sessions;
ss >> max_sessions;
ASSERT_FALSE(ss.fail());
EXPECT_TRUE(ss.eof());
EXPECT_LE(open_sessions, max_sessions);
EXPECT_LE(8u, max_sessions);
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(
kLevel3, wvcdm::QUERY_KEY_OEMCRYPTO_API_VERSION, &value));
ss.clear();
ss.str(value);
uint32_t api_version;
ss >> api_version;
ASSERT_FALSE(ss.fail());
EXPECT_TRUE(ss.eof());
EXPECT_LE(10u, api_version);
}
TEST_F(WvCdmRequestLicenseTest, QueryKeyControlInfo) {
Unprovision();
Provision(kLevelDefault);
@@ -2280,18 +2327,16 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
GetOfflineConfiguration(&key_id, &client_auth);
CdmQueryMap query_info;
CdmQueryMap::iterator itr;
std::string level;
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault, &query_info));
itr = query_info.find(wvcdm::QUERY_KEY_SECURITY_LEVEL);
ASSERT_TRUE(itr != query_info.end());
EXPECT_EQ(2u, itr->second.size());
EXPECT_TRUE(itr->second.compare(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3) == 0 ||
itr->second.compare(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1) == 0);
decryptor_.QueryStatus(kLevelDefault,
wvcdm::QUERY_KEY_SECURITY_LEVEL,
&level));
EXPECT_TRUE(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3 == level ||
wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1 == level);
CdmSecurityLevel security_level =
(itr->second.compare(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1) == 0)
wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1 == level
? kSecurityLevelL1
: kSecurityLevelL3;