Merge "Prevent segfaults when a session is deallocated" into oc-dev
am: 518ce632f7
Change-Id: Ibb52c6689a6693795288e0d9c7fdf88ea972045f
This commit is contained in:
@@ -1286,6 +1286,7 @@ CdmResponseType CdmEngine::Decrypt(const CdmSessionId& session_id,
|
||||
// else we must be level 1 direct and we don't need to return a buffer.
|
||||
}
|
||||
|
||||
AutoLock lock(session_list_lock_);
|
||||
CdmSessionMap::iterator session_iter = sessions_.end();
|
||||
if (session_id.empty()) {
|
||||
// Loop through the sessions to find the session containing the key_id
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "string_conversions.h"
|
||||
#include "test_base.h"
|
||||
#include "url_request.h"
|
||||
#include <utils/Thread.h>
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "wv_content_decryption_module.h"
|
||||
|
||||
@@ -678,6 +679,43 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
|
||||
return security_level;
|
||||
}
|
||||
|
||||
class CloseSessionThread : public android::Thread {
|
||||
public:
|
||||
CloseSessionThread() :
|
||||
Thread(false),
|
||||
wv_content_decryption_module_(NULL) {}
|
||||
~CloseSessionThread() {}
|
||||
|
||||
bool Start(WvContentDecryptionModule* decryptor,
|
||||
const CdmSessionId& session_id,
|
||||
uint32_t time_in_msecs) {
|
||||
wv_content_decryption_module_ = decryptor;
|
||||
sess_id_ = session_id;
|
||||
delay_.tv_sec = time_in_msecs / 1000;
|
||||
delay_.tv_nsec = (time_in_msecs % 1000) * 10000000ll;
|
||||
return run("CloseSessionThread") == android::NO_ERROR;
|
||||
}
|
||||
|
||||
void Stop() { requestExitAndWait(); }
|
||||
|
||||
private:
|
||||
virtual bool threadLoop() {
|
||||
struct timespec delay_remaining;
|
||||
int result = nanosleep(&delay_, &delay_remaining);
|
||||
while (result < 0 &&
|
||||
(delay_remaining.tv_sec > 0 || delay_remaining.tv_nsec > 0)) {
|
||||
result = nanosleep(&delay_remaining, &delay_remaining);
|
||||
}
|
||||
wv_content_decryption_module_->CloseSession(sess_id_);
|
||||
return false;
|
||||
}
|
||||
|
||||
WvContentDecryptionModule* wv_content_decryption_module_;
|
||||
CdmSessionId sess_id_;
|
||||
struct timespec delay_;
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(CloseSessionThread);
|
||||
};
|
||||
|
||||
WvContentDecryptionModule decryptor_;
|
||||
CdmKeyMessage key_msg_;
|
||||
CdmKeyResponse key_response_;
|
||||
@@ -831,6 +869,74 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRenewalTest) {
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmExtendedDurationTest, DecryptionCloseSessionConcurrencyTest) {
|
||||
Unprovision();
|
||||
Provision();
|
||||
|
||||
// Leave session open to avoid CDM termination
|
||||
CdmSessionId session_id;
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id);
|
||||
|
||||
// Retrieve offline license
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(kOfflineClip2PstInitData, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
for (uint32_t j = 0; j < 500; ++j) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id_));
|
||||
|
||||
CdmResponseType status = NO_ERROR;
|
||||
struct timespec decrypt_delay;
|
||||
decrypt_delay.tv_sec = 0;
|
||||
decrypt_delay.tv_nsec = 10000000ll; // 10 ms
|
||||
|
||||
CloseSessionThread* thread = new CloseSessionThread();
|
||||
thread->Start(&decryptor_, session_id_, 500 /* 500 ms */);
|
||||
thread = NULL;
|
||||
|
||||
while (status == NO_ERROR) {
|
||||
struct timespec delay_remaining;
|
||||
int result = nanosleep(&decrypt_delay, &delay_remaining);
|
||||
while (result < 0 &&
|
||||
(delay_remaining.tv_sec > 0 || delay_remaining.tv_nsec > 0)) {
|
||||
result = nanosleep(&delay_remaining, &delay_remaining);
|
||||
}
|
||||
SubSampleInfo* data = &kEncryptedOfflineClip2SubSample;
|
||||
for (size_t i = 0; i < data->num_of_subsamples; i++) {
|
||||
std::vector<uint8_t> decrypt_buffer((data + i)->encrypt_data.size());
|
||||
CdmDecryptionParameters decryption_parameters(
|
||||
&(data + i)->key_id, &(data + i)->encrypt_data.front(),
|
||||
(data + i)->encrypt_data.size(), &(data + i)->iv,
|
||||
(data + i)->block_offset, &decrypt_buffer[0]);
|
||||
decryption_parameters.is_encrypted = (data + i)->is_encrypted;
|
||||
decryption_parameters.is_secure = (data + i)->is_secure;
|
||||
decryption_parameters.subsample_flags = (data + i)->subsample_flags;
|
||||
status = decryptor_.Decrypt(session_id_, (data + i)->validate_key_id,
|
||||
decryption_parameters);
|
||||
|
||||
switch (status) {
|
||||
case SESSION_NOT_FOUND_FOR_DECRYPT:
|
||||
break;
|
||||
case NO_ERROR:
|
||||
EXPECT_EQ((data + i)->decrypt_data, decrypt_buffer);
|
||||
break;
|
||||
default:
|
||||
EXPECT_TRUE(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
decryptor_.CloseSession(session_id);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) {
|
||||
Provision();
|
||||
SubSampleInfo* data = &kEncryptedStreamingClip5SubSample;
|
||||
|
||||
Reference in New Issue
Block a user