Enable usage reporting
[ Merge from Widevine CDM repo of https://widevine-internal-review.googlesource.com/#/c/10171/ and https://widevine-internal-review.googlesource.com/#/c/10172/ ] Updated license_protocol.proto from constituent protos in google3 These changes make use of OEMCrypto v9 changes to support usage reporting. Usage reporting may be enabled for streaming (by means of secure stops) and offline playback by a provider session token specified in the license. Changes include periodically updating usage information for relevant sessions and reporting and releasing usage information as needed. The CDM has removed all references to Secure Stops. This change updates the Android API implementation to comply. b/11987015 Change-Id: Ibb6f2ced4ef20ee349ca1ae6412ce686b2b5d085
This commit is contained in:
@@ -236,6 +236,114 @@ SubSampleInfo single_encrypted_sub_sample_icp = {
|
||||
"58b938c2e3ca4c2ce48942da97f9e45797f2c074ac6004734e93784a48af6160"),
|
||||
wvcdm::a2b_hex("4cca615fc013102892f91efee936639b"), 0};
|
||||
|
||||
SubSampleInfo usage_info_sub_samples_icp[] = {
|
||||
{true, 1, true, true, false,
|
||||
wvcdm::a2bs_hex("E82DDD1D07CBB31CDD31EBAAE0894609"),
|
||||
wvcdm::a2b_hex(
|
||||
"fe8670a01c86906c056b4bf85ad278464c4eb79c60de1da8480e66e78561350e"
|
||||
"a25ae19a001f834c43aaeadf900b3c5a6745e885a4d1d1ae5bafac08dc1d60e5"
|
||||
"f3465da303909ec4b09023490471f670b615d77db844192854fdab52b7806203"
|
||||
"89b374594bbb6a2f2fcc31036d7cb8a3f80c0e27637b58a7650028fbf2470d68"
|
||||
"1bbd77934af165d215ef325c74438c9d99a20fc628792db28c05ed5deff7d9d4"
|
||||
"dba02ddb6cf11dc6e78cb5200940af9a2321c3a7c4c79be67b54a744dae1209c"
|
||||
"fa02fc250ce18d30c7da9c3a4a6c9619bf8561a42ff1e55a7b14fa3c8de69196"
|
||||
"c2b8e3ff672fc37003b479da5d567b7199917dbe5aa402890ebb066bce140b33"),
|
||||
wvcdm::a2b_hex(
|
||||
"d08733bd0ef671f467906b50ff8322091400f86fd6f016fea2b86e33923775b3"
|
||||
"ebb4c8c6f3ba8b78dd200a74d3872a40264ab99e1d422e4f819abb7f249114aa"
|
||||
"b334420b37c86ce81938615ab9d3a6b2de8db545cd88e35091031e73016fb386"
|
||||
"1b754298329b52dbe483de3a532277815e659f3e05e89257333225b933d92e15"
|
||||
"ef2deff287a192d2c8fc942a29a5f3a1d54440ac6385de7b34bb650b889e4ae9"
|
||||
"58c957b5f5ff268f445c0a6b825fcad55290cb7b5c9814bc4c72984dcf4c8fd7"
|
||||
"5f511c173b2e0a3163b18a1eac58539e5c188aeb0751b946ad4dcd08ea777a7f"
|
||||
"37326df26fa509343faa98dff667629f557873f1284903202e451227ef465a62"),
|
||||
wvcdm::a2b_hex("7362b5140c4ce0cd5f863858668d3f1a"), 0},
|
||||
{true, 1, true, true, false,
|
||||
wvcdm::a2bs_hex("04B2B456405CAD7170BE848CA75AA2DF"),
|
||||
wvcdm::a2b_hex(
|
||||
"ccb68f97b03e7af1a9e208d91655ba645cc5a5d454f3cb7c3d621e98a7592d90"
|
||||
"4ff7023555f0e99bcf3918948f4fca7a430faf17d7d67268d81d8096d7c48809"
|
||||
"c14220e634680fbe0c760571dd86a1905835035f4a238c2d7f17bd1363b113c1"
|
||||
"91782aebb77a1064142a68b59ecdcc6990ed4244082464d91dbfe09e08744b2f"
|
||||
"d1e850a008acbbe129fbd050c8dc1b28cb8cc2c1e2d920ea458f74809297b513"
|
||||
"85307b481cbb81d6759385ee782d6c0e101c20ca1937cfd0d6e024da1a0f718a"
|
||||
"fb7c4ff3df1ca87e67602d28168233cc2448d44b79f405d4c6e67eb88d705050"
|
||||
"2a806cb986423e3b0e7a97738e1d1d143b4f5f926a4e2f37c7fbe65f56d5b690"),
|
||||
wvcdm::a2b_hex(
|
||||
"fa35aa1f5e5d7b958880d5eed9cc1bb81d36ebd04c0250a8c752ea5f413bbdcf"
|
||||
"3785790c8dba7a0b21c71346bb7f946a9b71c0d2fe87d2e2fab14e35ee8400e7"
|
||||
"097a7d2d9a25b468e848e8dee2388f890967516c7dab96db4713c7855f717aed"
|
||||
"2ae9c2895baaa636e4a610ab26b35d771d62397ba40d78694dab70dcbdfa91c3"
|
||||
"6af79ad6b6ebb479b4a5fbc242a8574ebe6717f0813fbd6f726ce2af4d522e66"
|
||||
"b36c940fce519c913db56a6372c3636b10c0149b4cd97e74c576765b533abdc2"
|
||||
"729f1470dd7f9a60d3572dcc9839582a4606ee17eaced39797daef8f885d3f8f"
|
||||
"e14877ae530451c4242bbc3934f85a5bb71b363351894f881896471cfeaf68b2"),
|
||||
wvcdm::a2b_hex("4a59e3e5f3e4f7e2f494ad09c12a9e4c"), 0},
|
||||
{true, 1, true, true, false,
|
||||
wvcdm::a2bs_hex("3AE243D83B93B3311A1D777FF5FBE01A"),
|
||||
wvcdm::a2b_hex(
|
||||
"934997779aa1aeb45d6ba8845f13786575d0adf85a5e93674d9597f8d4286ed7"
|
||||
"dcce02f306e502bbd9f1cadf502f354038ca921276d158d911bdf3171d335b18"
|
||||
"0ae0f9abece16ff31ee263228354f724da2f3723b19caa38ea02bd6563b01208"
|
||||
"fb5bf57854ac0fe38d5883197ef90324b2721ff20fdcf9a53819515e6daa096e"
|
||||
"70f6f5c1d29a4a13dafd127e2e1f761ea0e28fd451607552ecbaef5da3c780bc"
|
||||
"aaf2667b4cc4f858f01d480cac9e32c3fbb5705e5d2adcceebefc2535c117208"
|
||||
"e65f604799fc3d7223e16908550f287a4bea687008cb0064cf14d3aeedb8c705"
|
||||
"09ebc5c2b8b5315f43c04d78d2f55f4b32c7d33e157114362106395cc0bb6d93"),
|
||||
wvcdm::a2b_hex(
|
||||
"2dd54eee1307753508e1f250d637044d6e8f5abf057dab73e9e95f83910e4efc"
|
||||
"191c9bac63950f13fd51833dd94a4d03f2b64fb5c721970c418fe53fa6f74ad5"
|
||||
"a6e16477a35c7aa6e28909b069cd25770ef80da20918fc30fe95fd5c87fd3522"
|
||||
"1649de17ca2c7b3dc31f936f0cbdf97c7b1c15de3a86b279dc4b4de64943914a"
|
||||
"99734556c4b7a1a0b022c1933cb0786068fc18d49fed2f2b49f3ac6d01c32d07"
|
||||
"92175ce2844eaf9064e6a3fcffade038d690cbed81659351163a22432f0d0545"
|
||||
"037e1c805d8e92a1272b4196ad0ce22f26bb80063137a8e454d3b97e2414283d"
|
||||
"ed0716cd8bceb80cf59166a217006bd147c51b04dfb183088ce3f51e9b9f759e"),
|
||||
wvcdm::a2b_hex("b358ab21ac90455bbf60490daad457e3"), 0},
|
||||
{true, 1, true, true, false,
|
||||
wvcdm::a2bs_hex("5292104C011418973C31235953FC8205"),
|
||||
wvcdm::a2b_hex(
|
||||
"d433adfd3d892d5c3e7d54ab0218ee0712400a920d4b71d553912451169f9b79"
|
||||
"3f103260cf04c34f6a5944bb96da79946a62bdbcd804ca28b17656338edfa700"
|
||||
"5c090f2750663a026fd15a0b0e448adbbfd53f613ea3993d9fd504421b575f28"
|
||||
"12020bb8cca0ce333eabee0403df9f410c6473d7673d6991caab6ea2ece8f743"
|
||||
"5a3ca049fa00c96c9b7c47e3073d25d08f23b47ffc509c48a81a2f98c9ec8a1d"
|
||||
"e41764c14a5010df8b4692e8612a45bf0645601d4910119e6268ca4f6d8016a8"
|
||||
"3d933d53f44243674b522bae43043c068c8cae43f0ac224198de71315b3a6f82"
|
||||
"c1b523bbdcdb3e9f162c308684dd17e364b448ed0e90b0e496b8cf633a982708"),
|
||||
wvcdm::a2b_hex(
|
||||
"5efb5e5b913785e9935e67e763b8ff29a6687ac6c18d5a7e16951beb704f9c95"
|
||||
"f081ca28f54c3e237fb5a7b0444e9a3e17da91e5cf2c0a8f009a873fb079c339"
|
||||
"81b0ebc565b2c56d983ee33686fa5057c9891e246b67bb6950400acb06d5ae50"
|
||||
"0e61a7e9289ea67ec2e88e8d0cc3c494fd996e93270e9b264a21818987e969c5"
|
||||
"1e2955c5a53202e5aec1e2c906e1c006325112eb5c33ee37d0c07ea97d80c17f"
|
||||
"d56e0efcf40c8c98981a86c18a159f05d851891236c124641d4584c49ccd7478"
|
||||
"4f328a9cacae0f945238d98741b2969fe258903e85f963daba7168f05c18b09f"
|
||||
"660dae18de41b1c49769cd38e24b135c37a65b69533f5c7d085898faedfbed5d"),
|
||||
wvcdm::a2b_hex("cef7e8aaa6ec1154cb68a988f7c9e803"), 0},
|
||||
{true, 1, true, true, false,
|
||||
wvcdm::a2bs_hex("D7C01C2F868AE314BCB893E4E9C6AC75"),
|
||||
wvcdm::a2b_hex(
|
||||
"fa5d28677721de488ffc209321529728c77bc338accd45ccc98ab2063fc8c373"
|
||||
"48c7698534175d72bf185690d19474d08c4fd4ed4eb46d858633f05337d70e92"
|
||||
"03f7ee6bec0f7003bdf6fa665ba172855a51a82da406348ba651a2f62888c30a"
|
||||
"7b4e1355bb94a9ff5c458f397c9a09e5d7785b286ef83142ddad324cc74e1929"
|
||||
"60ad1c34c425cdefbedcb62ca9b21ac4f3df7f5922e263cb7798de54b622ab3f"
|
||||
"64a0dd6ee1e40be6ecc857e657994ecac02ccfafc9036f382d7dbdf35c903356"
|
||||
"40b7c9db088143060b24f24b21c4a7c2faeb3d308e57c5a75955fd704cfe4dee"
|
||||
"71a4a7d823102b90eddded795ca6eb36282d777db8cfd783e50e5c2a816ee9ed"),
|
||||
wvcdm::a2b_hex(
|
||||
"d5db2f50c0f5a39414ddfa5129c2c641836a8c6312b26a210c996988e0c768d5"
|
||||
"9a3adff117293b52b0653c0d6e22589edda804fb8caa7442362fe4caf9053b6a"
|
||||
"2a34896399259a188f0c805de54b091a7eabff098b28d54584c01dd83301e4ca"
|
||||
"a01b226c4541af1592d4440e103eb55bbd08c471efb0856ec9ced43211fc3325"
|
||||
"3d402dff0d15f40833dd71259a8d40d527659ef3e5f9fd0826c9471dddb17e1e"
|
||||
"fab916abc957fb07d7eac4a368ac92a8fb16d995613af47303034ee57b59b1d7"
|
||||
"101aa031f5586b2f6b4c74372c4d7306db02509b5924d52c46a270f427743a85"
|
||||
"614f080d83f3b15cbc6600ddda43adff5d2941da13ebe49d80fd0cea5025412b"),
|
||||
wvcdm::a2b_hex("964c2dfda920357c668308d52d33c652"), 0}
|
||||
};
|
||||
|
||||
// License duration + fudge factor
|
||||
const uint32_t kSingleEncryptedSubSampleIcpLicenseDurationExpiration = 5 + 2;
|
||||
|
||||
@@ -253,6 +361,17 @@ SessionSharingSubSampleInfo session_sharing_sub_samples[] = {
|
||||
{ &single_encrypted_sub_sample, true }
|
||||
};
|
||||
|
||||
struct UsageInfoSubSampleInfo {
|
||||
SubSampleInfo* sub_sample;
|
||||
uint32_t usage_info;
|
||||
};
|
||||
|
||||
UsageInfoSubSampleInfo usage_info_sub_sample_info[] = {
|
||||
{ &usage_info_sub_samples_icp[0], 1 },
|
||||
{ &usage_info_sub_samples_icp[0], 3 },
|
||||
{ &usage_info_sub_samples_icp[0], 5 }
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace wvcdm {
|
||||
@@ -408,6 +527,33 @@ class WvCdmRequestLicenseTest : public testing::Test {
|
||||
return message;
|
||||
}
|
||||
|
||||
// Post a request and extract the signed provisioning message from
|
||||
// the HTTP response.
|
||||
std::string GetUsageInfoResponse(const std::string& server_url,
|
||||
const std::string& client_auth,
|
||||
const std::string& usage_info_request) {
|
||||
// Use secure connection and chunk transfer coding.
|
||||
UrlRequest url_request(server_url + client_auth, g_port,
|
||||
g_use_secure_transfer, g_use_chunked_transfer);
|
||||
if (!url_request.is_connected()) {
|
||||
return "";
|
||||
}
|
||||
url_request.PostRequest(usage_info_request);
|
||||
std::string message;
|
||||
int resp_bytes = url_request.GetResponse(&message);
|
||||
|
||||
int status_code = url_request.GetStatusCode(message);
|
||||
EXPECT_EQ(kHttpOk, status_code);
|
||||
|
||||
std::string usage_info;
|
||||
if (kHttpOk == status_code) {
|
||||
LicenseRequest license;
|
||||
license.GetDrmMessage(message, usage_info);
|
||||
LOGV("HTTP response body: (%u bytes)", usage_info.size());
|
||||
}
|
||||
return usage_info;
|
||||
}
|
||||
|
||||
void VerifyKeyRequestResponse(const std::string& server_url,
|
||||
const std::string& client_auth,
|
||||
std::string& init_data, bool is_renewal) {
|
||||
@@ -586,7 +732,8 @@ TEST_F(WvCdmRequestLicenseTest, ForceL3Test) {
|
||||
|
||||
File file;
|
||||
DeviceFiles handle;
|
||||
EXPECT_TRUE(handle.Init(&file, kSecurityLevelL3));
|
||||
EXPECT_TRUE(handle.Init(kSecurityLevelL3));
|
||||
handle.SetTestFile(&file);
|
||||
EXPECT_TRUE(handle.DeleteAllFiles());
|
||||
|
||||
EXPECT_EQ(NEED_PROVISIONING,
|
||||
@@ -766,6 +913,80 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) {
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
class WvCdmUsageInfoTest
|
||||
: public WvCdmRequestLicenseTest,
|
||||
public ::testing::WithParamInterface<UsageInfoSubSampleInfo*> {};
|
||||
|
||||
TEST_P(WvCdmUsageInfoTest, DISABLED_UsageInfo) {
|
||||
File file;
|
||||
DeviceFiles handle;
|
||||
|
||||
std::string level = GetSecurityLevel(NULL).c_str();
|
||||
CdmSecurityLevel security_level = kSecurityLevelUninitialized;
|
||||
if (level.compare(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1) == 0) {
|
||||
security_level = kSecurityLevelL1;
|
||||
} else if (level.compare(wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3) == 0) {
|
||||
security_level = kSecurityLevelL3;
|
||||
} else {
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
EXPECT_TRUE(handle.Init(security_level));
|
||||
handle.SetTestFile(&file);
|
||||
EXPECT_TRUE(handle.DeleteUsageInfo());
|
||||
|
||||
UsageInfoSubSampleInfo* usage_info_data = GetParam();
|
||||
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, NULL, &session_id_);
|
||||
std::string key_id = a2bs_hex(
|
||||
"000000427073736800000000" // blob size and pssh
|
||||
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
|
||||
"08011a0d7769646576696e655f74657374220f73" // pssh data
|
||||
"747265616d696e675f636c6970");
|
||||
|
||||
char ch = 0x33 + i;
|
||||
key_id.append(1, ch);
|
||||
|
||||
GenerateKeyRequest(g_key_system, key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, data->key_id,
|
||||
false);
|
||||
|
||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||
CdmDecryptionParameters decryption_parameters(
|
||||
&data->key_id, &data->encrypt_data.front(), data->encrypt_data.size(),
|
||||
&data->iv, data->block_offset, &decrypt_buffer[0]);
|
||||
decryption_parameters.is_encrypted = data->is_encrypted;
|
||||
decryption_parameters.is_secure = data->is_secure;
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id_, data->validate_key_id,
|
||||
decryption_parameters));
|
||||
|
||||
EXPECT_TRUE(std::equal(data->decrypt_data.begin(), data->decrypt_data.end(),
|
||||
decrypt_buffer.begin()));
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
uint32_t num_usage_info = 0;
|
||||
CdmUsageInfo usage_info;
|
||||
CdmUsageInfoReleaseMessage release_msg;
|
||||
CdmResponseType status = decryptor_.GetUsageInfo(&usage_info);
|
||||
EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status);
|
||||
while (usage_info.size() > 0) {
|
||||
for (size_t i = 0; i < usage_info.size(); ++i) {
|
||||
release_msg = GetUsageInfoResponse(g_license_server, g_client_auth,
|
||||
usage_info[i]);
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg));
|
||||
}
|
||||
status = decryptor_.GetUsageInfo(&usage_info);
|
||||
EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status);
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Cdm, WvCdmUsageInfoTest,
|
||||
::testing::Values(&usage_info_sub_sample_info[0],
|
||||
&usage_info_sub_sample_info[1],
|
||||
&usage_info_sub_sample_info[2]));
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, QueryUnmodifiedSessionStatus) {
|
||||
// Test that the global value is returned when no properties are modifying it.
|
||||
CdmQueryMap system_query_info;
|
||||
|
||||
Reference in New Issue
Block a user