Release offline release sessions -- DO NOT MERGE
am: 9a55ca3249
Change-Id: If92d87a6d1cf98a786c72070122d7db68444be4f
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "certificate_provisioning.h"
|
#include "certificate_provisioning.h"
|
||||||
|
#include "clock.h"
|
||||||
#include "crypto_session.h"
|
#include "crypto_session.h"
|
||||||
#include "initialization_data.h"
|
#include "initialization_data.h"
|
||||||
#include "lock.h"
|
#include "lock.h"
|
||||||
@@ -22,7 +23,10 @@ class UsagePropertySet;
|
|||||||
class WvCdmEventListener;
|
class WvCdmEventListener;
|
||||||
|
|
||||||
typedef std::map<CdmSessionId, CdmSession*> CdmSessionMap;
|
typedef std::map<CdmSessionId, CdmSession*> CdmSessionMap;
|
||||||
typedef std::map<CdmKeySetId, CdmSessionId> CdmReleaseKeySetMap;
|
typedef std::map<
|
||||||
|
CdmKeySetId,
|
||||||
|
std::pair<CdmSessionId, int64_t /* expiration time in seconds */> >
|
||||||
|
CdmReleaseKeySetMap;
|
||||||
|
|
||||||
class CdmEngine {
|
class CdmEngine {
|
||||||
public:
|
public:
|
||||||
@@ -185,11 +189,14 @@ class CdmEngine {
|
|||||||
|
|
||||||
std::string MapHdcpVersion(CryptoSession::HdcpCapability version);
|
std::string MapHdcpVersion(CryptoSession::HdcpCapability version);
|
||||||
|
|
||||||
|
void CloseExpiredReleaseSessions();
|
||||||
|
|
||||||
// instance variables
|
// instance variables
|
||||||
CdmSessionMap sessions_;
|
CdmSessionMap sessions_;
|
||||||
CdmReleaseKeySetMap release_key_sets_;
|
CdmReleaseKeySetMap release_key_sets_;
|
||||||
scoped_ptr<CertificateProvisioning> cert_provisioning_;
|
scoped_ptr<CertificateProvisioning> cert_provisioning_;
|
||||||
SecurityLevel cert_provisioning_requested_security_level_;
|
SecurityLevel cert_provisioning_requested_security_level_;
|
||||||
|
Clock clock_;
|
||||||
|
|
||||||
static bool seeded_;
|
static bool seeded_;
|
||||||
|
|
||||||
@@ -206,6 +213,8 @@ class CdmEngine {
|
|||||||
// occur simultaneously with OpenSession or CloseSession.
|
// occur simultaneously with OpenSession or CloseSession.
|
||||||
Lock session_list_lock_;
|
Lock session_list_lock_;
|
||||||
|
|
||||||
|
Lock release_key_sets_lock_;
|
||||||
|
|
||||||
CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngine);
|
CORE_DISALLOW_COPY_AND_ASSIGN(CdmEngine);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "wv_cdm_event_listener.h"
|
#include "wv_cdm_event_listener.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
const uint64_t kReleaseSessionTimeToLive = 60; // seconds
|
||||||
const uint32_t kUpdateUsageInformationPeriod = 60; // seconds
|
const uint32_t kUpdateUsageInformationPeriod = 60; // seconds
|
||||||
const size_t kUsageReportsPerRequest = 1;
|
const size_t kUsageReportsPerRequest = 1;
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -62,8 +63,7 @@ CdmEngine::CdmEngine()
|
|||||||
last_usage_information_update_time_(0) {
|
last_usage_information_update_time_(0) {
|
||||||
Properties::Init();
|
Properties::Init();
|
||||||
if (!seeded_) {
|
if (!seeded_) {
|
||||||
Clock clock;
|
srand(clock_.GetCurrentTime());
|
||||||
srand(clock.GetCurrentTime());
|
|
||||||
seeded_ = true;
|
seeded_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,6 +119,8 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseExpiredReleaseSessions();
|
||||||
|
|
||||||
scoped_ptr<CdmSession> new_session(new CdmSession(origin));
|
scoped_ptr<CdmSession> new_session(new CdmSession(origin));
|
||||||
CdmResponseType sts = new_session->Init(property_set, forced_session_id,
|
CdmResponseType sts = new_session->Init(property_set, forced_session_id,
|
||||||
event_listener);
|
event_listener);
|
||||||
@@ -149,6 +151,14 @@ CdmResponseType CdmEngine::OpenKeySetSession(
|
|||||||
return EMPTY_KEYSET_ID_ENG_1;
|
return EMPTY_KEYSET_ID_ENG_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool exists = false;
|
||||||
|
{
|
||||||
|
AutoLock lock(release_key_sets_lock_);
|
||||||
|
exists = release_key_sets_.find(key_set_id) != release_key_sets_.end();
|
||||||
|
}
|
||||||
|
if (exists)
|
||||||
|
CloseKeySetSession(key_set_id);
|
||||||
|
|
||||||
CdmSessionId session_id;
|
CdmSessionId session_id;
|
||||||
CdmResponseType sts =
|
CdmResponseType sts =
|
||||||
OpenSession(KEY_SYSTEM, property_set, origin, event_listener,
|
OpenSession(KEY_SYSTEM, property_set, origin, event_listener,
|
||||||
@@ -156,7 +166,10 @@ CdmResponseType CdmEngine::OpenKeySetSession(
|
|||||||
|
|
||||||
if (sts != NO_ERROR) return sts;
|
if (sts != NO_ERROR) return sts;
|
||||||
|
|
||||||
release_key_sets_[key_set_id] = session_id;
|
AutoLock lock(release_key_sets_lock_);
|
||||||
|
release_key_sets_[key_set_id] = std::make_pair(session_id,
|
||||||
|
clock_.GetCurrentTime() + kReleaseSessionTimeToLive);
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,19 +190,30 @@ CdmResponseType CdmEngine::CloseSession(const CdmSessionId& session_id) {
|
|||||||
CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) {
|
CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) {
|
||||||
LOGI("CdmEngine::CloseKeySetSession");
|
LOGI("CdmEngine::CloseKeySetSession");
|
||||||
|
|
||||||
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
CdmSessionId session_id;
|
||||||
if (iter == release_key_sets_.end()) {
|
{
|
||||||
LOGE("CdmEngine::CloseKeySetSession: key set id not found = %s",
|
AutoLock lock(release_key_sets_lock_);
|
||||||
key_set_id.c_str());
|
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
||||||
return KEYSET_ID_NOT_FOUND_1;
|
if (iter == release_key_sets_.end()) {
|
||||||
|
LOGE("CdmEngine::CloseKeySetSession: key set id not found = %s",
|
||||||
|
key_set_id.c_str());
|
||||||
|
return KEYSET_ID_NOT_FOUND_1;
|
||||||
|
}
|
||||||
|
session_id = iter->second.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmResponseType sts = CloseSession(iter->second);
|
CdmResponseType sts = CloseSession(session_id);
|
||||||
release_key_sets_.erase(iter);
|
|
||||||
|
AutoLock lock(release_key_sets_lock_);
|
||||||
|
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
||||||
|
if (iter != release_key_sets_.end()) {
|
||||||
|
release_key_sets_.erase(iter);
|
||||||
|
}
|
||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdmEngine::IsOpenSession(const CdmSessionId& session_id) {
|
bool CdmEngine::IsOpenSession(const CdmSessionId& session_id) {
|
||||||
|
AutoLock lock(session_list_lock_);
|
||||||
CdmSessionMap::iterator iter = sessions_.find(session_id);
|
CdmSessionMap::iterator iter = sessions_.find(session_id);
|
||||||
return iter != sessions_.end();
|
return iter != sessions_.end();
|
||||||
}
|
}
|
||||||
@@ -218,6 +242,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
|
|||||||
return INVALID_SESSION_ID;
|
return INVALID_SESSION_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoLock lock(release_key_sets_lock_);
|
||||||
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
|
||||||
if (iter == release_key_sets_.end()) {
|
if (iter == release_key_sets_.end()) {
|
||||||
LOGE("CdmEngine::GenerateKeyRequest: key set ID not found = %s",
|
LOGE("CdmEngine::GenerateKeyRequest: key set ID not found = %s",
|
||||||
@@ -225,7 +250,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
|
|||||||
return KEYSET_ID_NOT_FOUND_2;
|
return KEYSET_ID_NOT_FOUND_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = iter->second;
|
id = iter->second.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmSessionMap::iterator iter = sessions_.find(id);
|
CdmSessionMap::iterator iter = sessions_.find(id);
|
||||||
@@ -291,13 +316,14 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id,
|
|||||||
return EMPTY_KEYSET_ID_ENG_3;
|
return EMPTY_KEYSET_ID_ENG_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoLock lock(release_key_sets_lock_);
|
||||||
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(*key_set_id);
|
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(*key_set_id);
|
||||||
if (iter == release_key_sets_.end()) {
|
if (iter == release_key_sets_.end()) {
|
||||||
LOGE("CdmEngine::AddKey: key set id not found = %s", key_set_id->c_str());
|
LOGE("CdmEngine::AddKey: key set id not found = %s", key_set_id->c_str());
|
||||||
return KEYSET_ID_NOT_FOUND_3;
|
return KEYSET_ID_NOT_FOUND_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = iter->second;
|
id = iter->second.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
CdmSessionMap::iterator iter = sessions_.find(id);
|
CdmSessionMap::iterator iter = sessions_.find(id);
|
||||||
@@ -1159,6 +1185,8 @@ void CdmEngine::OnTimerEvent() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseExpiredReleaseSessions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) {
|
void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) {
|
||||||
@@ -1188,6 +1216,29 @@ std::string CdmEngine::MapHdcpVersion(
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CdmEngine::CloseExpiredReleaseSessions() {
|
||||||
|
int64_t current_time = clock_.GetCurrentTime();
|
||||||
|
|
||||||
|
std::set<CdmSessionId> close_session_set;
|
||||||
|
{
|
||||||
|
AutoLock lock(release_key_sets_lock_);
|
||||||
|
for (CdmReleaseKeySetMap::iterator iter = release_key_sets_.begin();
|
||||||
|
iter != release_key_sets_.end();) {
|
||||||
|
if (iter->second.second < current_time) {
|
||||||
|
close_session_set.insert(iter->second.first);
|
||||||
|
release_key_sets_.erase(iter++);
|
||||||
|
} else {
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::set<CdmSessionId>::iterator iter = close_session_set.begin();
|
||||||
|
iter != close_session_set.end(); ++iter) {
|
||||||
|
CloseSession(*iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CdmEngine::DeleteAllUsageReportsUponFactoryReset() {
|
void CdmEngine::DeleteAllUsageReportsUponFactoryReset() {
|
||||||
std::string device_base_path_level1 = "";
|
std::string device_base_path_level1 = "";
|
||||||
std::string device_base_path_level3 = "";
|
std::string device_base_path_level3 = "";
|
||||||
|
|||||||
@@ -166,6 +166,14 @@ std::string kOfflineClip2PstInitData = wvcdm::a2bs_hex(
|
|||||||
"08011a0d7769646576696e655f74657374220d6f" // pssh data
|
"08011a0d7769646576696e655f74657374220d6f" // pssh data
|
||||||
"66666c696e655f636c697032");
|
"66666c696e655f636c697032");
|
||||||
|
|
||||||
|
std::string kOfflineClip4 = wvcdm::a2bs_hex(
|
||||||
|
"000000427073736800000000" // blob size and pssh
|
||||||
|
"EDEF8BA979D64ACEA3C827DCD51D21ED00000020" // Widevine system id
|
||||||
|
"08011a0d7769646576696e655f74657374220d6f" // pssh data
|
||||||
|
"66666c696e655f636c697034");
|
||||||
|
|
||||||
|
std::string kUatLicenseServer = "https://proxy.uat.widevine.com/proxy";
|
||||||
|
|
||||||
bool StringToInt64(const std::string& input, int64_t* output) {
|
bool StringToInt64(const std::string& input, int64_t* output) {
|
||||||
std::istringstream ss(input);
|
std::istringstream ss(input);
|
||||||
ss >> *output;
|
ss >> *output;
|
||||||
@@ -286,19 +294,26 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
|
|||||||
EXPECT_NE(0u, key_request.url.size());
|
EXPECT_NE(0u, key_request.url.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateKeyRelease(CdmKeySetId key_set_id) {
|
void GenerateKeyRelease(CdmKeySetId key_set_id,
|
||||||
|
CdmResponseType expected_response) {
|
||||||
CdmSessionId session_id;
|
CdmSessionId session_id;
|
||||||
CdmInitData init_data;
|
CdmInitData init_data;
|
||||||
CdmAppParameterMap app_parameters;
|
CdmAppParameterMap app_parameters;
|
||||||
CdmKeyRequest key_request;
|
CdmKeyRequest key_request;
|
||||||
|
|
||||||
EXPECT_EQ(KEY_MESSAGE, decryptor_.GenerateKeyRequest(
|
EXPECT_EQ(expected_response, decryptor_.GenerateKeyRequest(
|
||||||
session_id, key_set_id, "video/mp4", init_data,
|
session_id, key_set_id, "video/mp4", init_data,
|
||||||
kLicenseTypeRelease, app_parameters, NULL,
|
kLicenseTypeRelease, app_parameters, NULL,
|
||||||
EMPTY_ORIGIN, &key_request));
|
EMPTY_ORIGIN, &key_request));
|
||||||
|
|
||||||
key_msg_ = key_request.message;
|
if (expected_response == KEY_MESSAGE) {
|
||||||
EXPECT_EQ(kKeyRequestTypeRelease, key_request.type);
|
key_msg_ = key_request.message;
|
||||||
|
EXPECT_EQ(kKeyRequestTypeRelease, key_request.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateKeyRelease(CdmKeySetId key_set_id) {
|
||||||
|
GenerateKeyRelease(key_set_id, KEY_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogResponseError(const std::string& message, int http_status_code) {
|
void LogResponseError(const std::string& message, int http_status_code) {
|
||||||
@@ -612,6 +627,19 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
|
|||||||
EXPECT_TRUE(StringToInt64(query_info[key], playback_duration_remaining));
|
EXPECT_TRUE(StringToInt64(query_info[key], playback_duration_remaining));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t QueryStatus(SecurityLevel security_level, const std::string& key) {
|
||||||
|
std::string str;
|
||||||
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||||
|
decryptor_.QueryStatus(security_level, key, &str));
|
||||||
|
|
||||||
|
std::istringstream ss(str);
|
||||||
|
uint32_t value;
|
||||||
|
ss >> value;
|
||||||
|
EXPECT_FALSE(ss.fail());
|
||||||
|
EXPECT_TRUE(ss.eof());
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) {
|
std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) {
|
||||||
decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL,
|
decryptor_.OpenSession(g_key_system, property_set, EMPTY_ORIGIN, NULL,
|
||||||
&session_id_);
|
&session_id_);
|
||||||
@@ -837,6 +865,81 @@ TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that sessions allocated internally during
|
||||||
|
// key release message generation are deallocated after their
|
||||||
|
// time to live period expires.
|
||||||
|
// TODO: Disabled till b/32617908 is addressed
|
||||||
|
TEST_F(WvCdmExtendedDurationTest, DISABLED_AutomatedOfflineSessionReleaseTest) {
|
||||||
|
Unprovision();
|
||||||
|
Provision();
|
||||||
|
|
||||||
|
// override default settings unless configured through the command line
|
||||||
|
std::string key_id;
|
||||||
|
std::string client_auth;
|
||||||
|
GetOfflineConfiguration(&key_id, &client_auth);
|
||||||
|
|
||||||
|
uint32_t initial_open_sessions =
|
||||||
|
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
|
||||||
|
|
||||||
|
uint32_t max_sessions =
|
||||||
|
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS);
|
||||||
|
|
||||||
|
uint32_t num_key_set_ids = max_sessions - initial_open_sessions;
|
||||||
|
if (num_key_set_ids > kMaxUsageTableSize)
|
||||||
|
num_key_set_ids = kMaxUsageTableSize;
|
||||||
|
|
||||||
|
std::set<std::string> key_set_id_map;
|
||||||
|
for (uint32_t i = 0; i < num_key_set_ids; ++i) {
|
||||||
|
decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
|
||||||
|
&session_id_);
|
||||||
|
GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline);
|
||||||
|
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
|
||||||
|
|
||||||
|
EXPECT_FALSE(key_set_id_.empty());
|
||||||
|
decryptor_.CloseSession(session_id_);
|
||||||
|
key_set_id_map.insert(key_set_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string>::iterator iter;
|
||||||
|
for (iter = key_set_id_map.begin(); iter != key_set_id_map.end(); ++iter) {
|
||||||
|
session_id_.clear();
|
||||||
|
key_set_id_.clear();
|
||||||
|
decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
|
||||||
|
&session_id_);
|
||||||
|
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, *iter));
|
||||||
|
decryptor_.CloseSession(session_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (iter = key_set_id_map.begin(); iter != key_set_id_map.end(); ++iter) {
|
||||||
|
session_id_.clear();
|
||||||
|
GenerateKeyRelease(*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t open_sessions =
|
||||||
|
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
|
||||||
|
|
||||||
|
EXPECT_EQ(open_sessions, key_set_id_map.size() + initial_open_sessions);
|
||||||
|
|
||||||
|
sleep(kMinute + kClockTolerance);
|
||||||
|
|
||||||
|
iter = key_set_id_map.begin();
|
||||||
|
session_id_.clear();
|
||||||
|
GenerateKeyRelease(*iter);
|
||||||
|
|
||||||
|
open_sessions =
|
||||||
|
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
|
||||||
|
|
||||||
|
EXPECT_GE(open_sessions, initial_open_sessions);
|
||||||
|
EXPECT_LE(open_sessions - initial_open_sessions, key_set_id_map.size());
|
||||||
|
|
||||||
|
for (iter = key_set_id_map.begin(); iter != key_set_id_map.end(); ++iter) {
|
||||||
|
session_id_.clear();
|
||||||
|
GenerateKeyRelease(*iter);
|
||||||
|
key_set_id_ = *iter;
|
||||||
|
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class WvCdmStreamingNoPstTest : public WvCdmExtendedDurationTest,
|
class WvCdmStreamingNoPstTest : public WvCdmExtendedDurationTest,
|
||||||
public ::testing::WithParamInterface<size_t> {};
|
public ::testing::WithParamInterface<size_t> {};
|
||||||
|
|
||||||
|
|||||||
@@ -1211,6 +1211,19 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
|||||||
return security_level;
|
return security_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t QueryStatus(SecurityLevel security_level, const std::string& key) {
|
||||||
|
std::string str;
|
||||||
|
EXPECT_EQ(wvcdm::NO_ERROR,
|
||||||
|
decryptor_.QueryStatus(security_level, key, &str));
|
||||||
|
|
||||||
|
std::istringstream ss(str);
|
||||||
|
uint32_t value;
|
||||||
|
ss >> value;
|
||||||
|
EXPECT_FALSE(ss.fail());
|
||||||
|
EXPECT_TRUE(ss.eof());
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
wvcdm::WvContentDecryptionModule decryptor_;
|
wvcdm::WvContentDecryptionModule decryptor_;
|
||||||
CdmKeyMessage key_msg_;
|
CdmKeyMessage key_msg_;
|
||||||
CdmSessionId session_id_;
|
CdmSessionId session_id_;
|
||||||
@@ -1817,6 +1830,60 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
|
|||||||
decryptor_.CloseSession(restore_session_id);
|
decryptor_.CloseSession(restore_session_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that repeated generation of the key release message
|
||||||
|
// for the same key_set_id results in the previous session being
|
||||||
|
// deallocated (rather than leaked) and a new one allocated.
|
||||||
|
TEST_F(WvCdmRequestLicenseTest, AutomatedOfflineSessionReleaseTest) {
|
||||||
|
Unprovision();
|
||||||
|
Provision(kLevelDefault);
|
||||||
|
|
||||||
|
// override default settings unless configured through the command line
|
||||||
|
std::string key_id;
|
||||||
|
std::string client_auth;
|
||||||
|
GetOfflineConfiguration(&key_id, &client_auth);
|
||||||
|
|
||||||
|
decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
|
||||||
|
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||||
|
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||||
|
|
||||||
|
CdmKeySetId key_set_id = key_set_id_;
|
||||||
|
EXPECT_FALSE(key_set_id_.empty());
|
||||||
|
decryptor_.CloseSession(session_id_);
|
||||||
|
|
||||||
|
session_id_.clear();
|
||||||
|
key_set_id_.clear();
|
||||||
|
decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
|
||||||
|
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
|
||||||
|
decryptor_.CloseSession(session_id_);
|
||||||
|
|
||||||
|
uint32_t open_sessions =
|
||||||
|
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
|
||||||
|
|
||||||
|
session_id_.clear();
|
||||||
|
key_set_id_.clear();
|
||||||
|
GenerateKeyRelease(key_set_id);
|
||||||
|
key_set_id_ = key_set_id;
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
++open_sessions,
|
||||||
|
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS));
|
||||||
|
|
||||||
|
session_id_.clear();
|
||||||
|
key_set_id_.clear();
|
||||||
|
GenerateKeyRelease(key_set_id);
|
||||||
|
key_set_id_ = key_set_id;
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
open_sessions,
|
||||||
|
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS));
|
||||||
|
|
||||||
|
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
--open_sessions,
|
||||||
|
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewal) {
|
TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewal) {
|
||||||
decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
|
decryptor_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL, &session_id_);
|
||||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||||
|
|||||||
Reference in New Issue
Block a user