resolved conflicts for merge of f111bea1 to master

Change-Id: I7f95eba8d5fb1e9a20800b9c1ef7fcb813eff41c
This commit is contained in:
John "Juce" Bruce
2014-03-31 17:35:24 -07:00
16 changed files with 330 additions and 107 deletions

View File

@@ -35,6 +35,7 @@ class CdmEngine {
// Construct a valid license request
CdmResponseType GenerateKeyRequest(const CdmSessionId& session_id,
const CdmKeySetId& key_set_id,
const std::string& mime_type,
const CdmInitData& init_data,
const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters,

View File

@@ -36,7 +36,8 @@ class CdmSession {
bool VerifySession(const CdmKeySystem& key_system,
const CdmInitData& init_data);
CdmResponseType GenerateKeyRequest(const CdmInitData& init_data,
CdmResponseType GenerateKeyRequest(const std::string& mime_type,
const CdmInitData& init_data,
const CdmLicenseType license_type,
const CdmAppParameterMap& app_parameters,
CdmKeyMessage* key_request,
@@ -109,7 +110,7 @@ class CdmSession {
CdmLicenseType license_type_;
// license type offline related information
CdmInitData offline_pssh_data_;
CdmInitData offline_init_data_;
CdmKeyMessage offline_key_request_;
CdmKeyResponse offline_key_response_;
CdmKeyMessage offline_key_renewal_request_;

View File

@@ -27,7 +27,8 @@ class CdmLicense {
bool Init(const std::string& token, CryptoSession* session,
PolicyEngine* policy_engine);
bool PrepareKeyRequest(const CdmInitData& pssh_data,
bool PrepareKeyRequest(const std::string& mime_type,
const CdmInitData& init_data,
const CdmLicenseType license_type,
const CdmAppParameterMap& app_parameters,
const CdmSessionId& session_id,
@@ -42,7 +43,7 @@ class CdmLicense {
bool RestoreOfflineLicense(CdmKeyMessage& license_request,
CdmKeyResponse& license_response,
CdmKeyResponse& license_renewal_response);
bool HasInitData() { return !init_data_.empty(); }
bool HasInitData() { return !stored_init_data_.empty(); }
bool IsKeyLoaded(const KeyId& key_id);
private:
@@ -54,12 +55,16 @@ class CdmLicense {
CdmResponseType HandleKeyErrorResponse(
const video_widevine_server::sdk::SignedMessage& signed_message);
template<typename T> bool PrepareContentId(const CdmLicenseType license_type,
const std::string& request_id,
T* content_id);
CryptoSession* session_;
PolicyEngine* policy_engine_;
std::string server_url_;
std::string token_;
std::string service_certificate_;
std::string init_data_;
std::string stored_init_data_;
bool initialized_;
std::set<KeyId> loaded_keys_;

View File

@@ -56,6 +56,8 @@ static const std::string QUERY_VALUE_SECURITY_LEVEL_L2 = "L2";
static const std::string QUERY_VALUE_SECURITY_LEVEL_L3 = "L3";
static const std::string QUERY_VALUE_SECURITY_LEVEL_UNKNOWN = "Unknown";
static const std::string ISO_BMFF_MIME_TYPE = "video/mp4";
static const std::string WEBM_MIME_TYPE = "video/webm";
} // namespace wvcdm
#endif // CDM_BASE_WV_CDM_CONSTANTS_H_

View File

@@ -118,6 +118,7 @@ CdmResponseType CdmEngine::CloseKeySetSession(const CdmKeySetId& key_set_id) {
CdmResponseType CdmEngine::GenerateKeyRequest(
const CdmSessionId& session_id,
const CdmKeySetId& key_set_id,
const std::string& mime_type,
const CdmInitData& init_data,
const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters,
@@ -173,7 +174,7 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
}
}
sts = iter->second->GenerateKeyRequest(init_data, license_type,
sts = iter->second->GenerateKeyRequest(mime_type, init_data, license_type,
app_parameters, key_request,
server_url);

View File

@@ -79,7 +79,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(
DeviceFiles::LicenseState license_state;
if (!handle.RetrieveLicense(key_set_id, &license_state, &offline_pssh_data_,
if (!handle.RetrieveLicense(key_set_id, &license_state, &offline_init_data_,
&offline_key_request_, &offline_key_response_,
&offline_key_renewal_request_,
&offline_key_renewal_response_,
@@ -122,9 +122,9 @@ bool CdmSession::VerifySession(const CdmKeySystem& key_system,
}
CdmResponseType CdmSession::GenerateKeyRequest(
const CdmInitData& init_data, const CdmLicenseType license_type,
const CdmAppParameterMap& app_parameters, CdmKeyMessage* key_request,
std::string* server_url) {
const std::string& mime_type, const CdmInitData& init_data,
const CdmLicenseType license_type, const CdmAppParameterMap& app_parameters,
CdmKeyMessage* key_request, std::string* server_url) {
if (reinitialize_session_) {
CdmResponseType sts = Init();
if (sts != NO_ERROR) {
@@ -152,14 +152,18 @@ CdmResponseType CdmSession::GenerateKeyRequest(
? UNKNOWN_ERROR
: GenerateRenewalRequest(key_request, server_url);
} else {
if (mime_type != ISO_BMFF_MIME_TYPE && mime_type != WEBM_MIME_TYPE) {
LOGW("CdmSession::GenerateKeyRequest: unknown MIME type");
return KEY_ERROR;
}
if (init_data.empty() && !license_parser_.HasInitData()) {
LOGW("CdmSession::GenerateKeyRequest: init data absent");
return KEY_ERROR;
}
CdmInitData pssh_data = init_data;
if (Properties::extract_pssh_data()) {
if (!CdmEngine::ExtractWidevinePssh(init_data, &pssh_data)) {
CdmInitData extracted_init_data = init_data;
if (Properties::extract_pssh_data() && mime_type == ISO_BMFF_MIME_TYPE) {
if (!CdmEngine::ExtractWidevinePssh(init_data, &extracted_init_data)) {
return KEY_ERROR;
}
}
@@ -174,14 +178,15 @@ CdmResponseType CdmSession::GenerateKeyRequest(
}
}
if (!license_parser_.PrepareKeyRequest(pssh_data, license_type,
app_parameters, session_id_,
key_request, server_url)) {
if (!license_parser_.PrepareKeyRequest(mime_type, extracted_init_data,
license_type, app_parameters,
session_id_, key_request,
server_url)) {
return KEY_ERROR;
}
if (license_type_ == kLicenseTypeOffline) {
offline_pssh_data_ = pssh_data;
offline_init_data_ = extracted_init_data;
offline_key_request_ = *key_request;
offline_release_server_url_ = *server_url;
}
@@ -415,7 +420,7 @@ bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) {
return false;
return handle.StoreLicense(
key_set_id_, state, offline_pssh_data_, offline_key_request_,
key_set_id_, state, offline_init_data_, offline_key_request_,
offline_key_response_, offline_key_renewal_request_,
offline_key_renewal_response_, offline_release_server_url_);
}

View File

@@ -84,6 +84,7 @@ using video_widevine_server::sdk::EncryptedClientIdentification;
using video_widevine_server::sdk::LicenseRequest;
using video_widevine_server::sdk::LicenseRequest_ContentIdentification;
using video_widevine_server::sdk::LicenseRequest_ContentIdentification_CENC;
using video_widevine_server::sdk::LicenseRequest_ContentIdentification_WebM;
using video_widevine_server::sdk::
LicenseRequest_ContentIdentification_ExistingLicense;
using video_widevine_server::sdk::License;
@@ -157,7 +158,8 @@ bool CdmLicense::Init(const std::string& token, CryptoSession* session,
return true;
}
bool CdmLicense::PrepareKeyRequest(const CdmInitData& init_data,
bool CdmLicense::PrepareKeyRequest(const std::string& mime_type,
const CdmInitData& init_data,
const CdmLicenseType license_type,
const CdmAppParameterMap& app_parameters,
const CdmSessionId& session_id,
@@ -167,7 +169,12 @@ bool CdmLicense::PrepareKeyRequest(const CdmInitData& init_data,
LOGE("CdmLicense::PrepareKeyRequest: not initialized");
return false;
}
if (init_data.empty() && init_data_.empty()) {
if (mime_type != ISO_BMFF_MIME_TYPE && mime_type != WEBM_MIME_TYPE) {
LOGE("CdmLicense::PrepareKeyRequest: unsupported MIME type %s",
mime_type.c_str());
return false;
}
if (init_data.empty() && stored_init_data_.empty()) {
LOGE("CdmLicense::PrepareKeyRequest: empty init data provided");
return false;
}
@@ -192,7 +199,7 @@ bool CdmLicense::PrepareKeyRequest(const CdmInitData& init_data,
serialized_service_certificate = service_certificate_;
if (privacy_mode_enabled && serialized_service_certificate.empty()) {
init_data_ = init_data;
stored_init_data_ = init_data;
return PrepareServiceCertificateRequest(signed_request, server_url);
}
@@ -308,33 +315,44 @@ bool CdmLicense::PrepareKeyRequest(const CdmInitData& init_data,
LicenseRequest_ContentIdentification* content_id =
license_request.mutable_content_id();
LicenseRequest_ContentIdentification_CENC* cenc_content_id =
content_id->mutable_cenc_id();
if (mime_type == ISO_BMFF_MIME_TYPE) {
LicenseRequest_ContentIdentification_CENC* cenc_content_id =
content_id->mutable_cenc_id();
if (!init_data.empty()) {
cenc_content_id->add_pssh(init_data);
} else if (privacy_mode_enabled && !init_data_.empty()) {
cenc_content_id->add_pssh(init_data_);
if (!init_data.empty()) {
cenc_content_id->add_pssh(init_data);
} else if (privacy_mode_enabled && !stored_init_data_.empty()) {
cenc_content_id->add_pssh(stored_init_data_);
} else {
LOGE("CdmLicense::PrepareKeyRequest: ISO-CENC init data not available");
return false;
}
if (!PrepareContentId(license_type, request_id, cenc_content_id)) {
return false;
}
} else if (mime_type == WEBM_MIME_TYPE) {
LicenseRequest_ContentIdentification_WebM* webm_content_id =
content_id->mutable_webm_id();
if (!init_data.empty()) {
webm_content_id->set_header(init_data);
} else if (privacy_mode_enabled && !stored_init_data_.empty()) {
webm_content_id->set_header(stored_init_data_);
} else {
LOGE("CdmLicense::PrepareKeyRequest: WebM init data not available");
return false;
}
if (!PrepareContentId(license_type, request_id, webm_content_id)) {
return false;
}
} else {
LOGD("CdmLicense::PrepareKeyRequest: init data not available");
LOGE("CdmLicense::PrepareKeyRequest: no support for MIME type %s",
mime_type.c_str());
return false;
}
switch (license_type) {
case kLicenseTypeOffline:
cenc_content_id->set_license_type(video_widevine_server::sdk::OFFLINE);
break;
case kLicenseTypeStreaming:
cenc_content_id->set_license_type(video_widevine_server::sdk::STREAMING);
break;
default:
LOGD("CdmLicense::PrepareKeyRequest: Unknown license type = %d",
license_type);
return false;
break;
}
cenc_content_id->set_request_id(request_id);
// TODO(jfore): The time field will be updated once the cdm wrapper
// has been updated to pass us in the time.
license_request.set_request_time(0);
@@ -766,6 +784,28 @@ CdmResponseType CdmLicense::HandleKeyErrorResponse(
}
}
template<typename T>
bool CdmLicense::PrepareContentId(const CdmLicenseType license_type,
const std::string& request_id,
T* content_id) {
switch (license_type) {
case kLicenseTypeOffline:
content_id->set_license_type(video_widevine_server::sdk::OFFLINE);
break;
case kLicenseTypeStreaming:
content_id->set_license_type(
video_widevine_server::sdk::STREAMING);
break;
default:
LOGD("CdmLicense::PrepareKeyRequest: Unknown license type = %d",
license_type);
return false;
}
content_id->set_request_id(request_id);
return true;
}
bool CdmLicense::IsKeyLoaded(const KeyId& key_id) {
return loaded_keys_.find(key_id) != loaded_keys_.end();
}

View File

@@ -16,6 +16,7 @@
#include "scoped_ptr.h"
#include "string_conversions.h"
#include "url_request.h"
#include "wv_cdm_constants.h"
#include "wv_cdm_types.h"
namespace {
@@ -99,20 +100,22 @@ class WvCdmEngineTest : public testing::Test {
protected:
void GenerateKeyRequest(const std::string& key_system,
const std::string& key_id) {
const std::string& key_id,
const std::string& mime_type) {
CdmAppParameterMap app_parameters;
std::string server_url;
std::string init_data = key_id;
CdmKeySetId key_set_id;
// TODO(rfrias): Temporary change till b/9465346 is addressed
if (!Properties::extract_pssh_data()) {
if (!Properties::extract_pssh_data() || mime_type != ISO_BMFF_MIME_TYPE) {
EXPECT_TRUE(CdmEngine::ExtractWidevinePssh(key_id, &init_data));
}
EXPECT_EQ(KEY_MESSAGE,
cdm_engine_.GenerateKeyRequest(session_id_,
key_set_id,
mime_type,
init_data,
kLicenseTypeStreaming,
app_parameters,
@@ -165,7 +168,7 @@ class WvCdmEngineTest : public testing::Test {
std::string resp = GetKeyRequestResponse(server_url,
client_auth);
CdmKeySetId key_set_id;
EXPECT_EQ(cdm_engine_.AddKey(session_id_, resp, &key_set_id), KEY_ADDED);
EXPECT_EQ(wvcdm::KEY_ADDED, cdm_engine_.AddKey(session_id_, resp, &key_set_id));
}
void VerifyRenewalKeyResponse(const std::string& server_url,
@@ -173,7 +176,7 @@ class WvCdmEngineTest : public testing::Test {
std::string& init_data) {
std::string resp = GetKeyRequestResponse(server_url,
client_auth);
EXPECT_EQ(cdm_engine_.RenewKey(session_id_, resp), wvcdm::KEY_ADDED);
EXPECT_EQ(wvcdm::KEY_ADDED, cdm_engine_.RenewKey(session_id_, resp));
}
CdmEngine cdm_engine_;
@@ -191,27 +194,39 @@ TEST(WvCdmProvisioningTest, ProvisioningTest) {
cdm_engine.HandleProvisioningResponse(kValidJsonProvisioningResponse);
}
TEST_F(WvCdmEngineTest, BaseMessageTest) {
GenerateKeyRequest(g_key_system, g_key_id);
TEST_F(WvCdmEngineTest, BaseIsoBmffMessageTest) {
GenerateKeyRequest(g_key_system, g_key_id, "video/mp4");
GetKeyRequestResponse(g_license_server, g_client_auth);
}
// TODO(juce): Set up with correct test data.
TEST_F(WvCdmEngineTest, DISABLED_BaseWebmMessageTest) {
GenerateKeyRequest(g_key_system, g_key_id, "video/webm");
GetKeyRequestResponse(g_license_server, g_client_auth);
}
TEST_F(WvCdmEngineTest, WrongMessageTest) {
std::string wrong_message = a2bs_hex(g_wrong_key_id);
GenerateKeyRequest(g_key_system, wrong_message);
GenerateKeyRequest(g_key_system, wrong_message, "video/mp4");
// We should receive a response with no license, i.e. the extracted license
// response message should be empty.
ASSERT_EQ("", GetKeyRequestResponse(g_license_server, g_client_auth));
}
TEST_F(WvCdmEngineTest, NormalDecryption) {
GenerateKeyRequest(g_key_system, g_key_id);
TEST_F(WvCdmEngineTest, NormalDecryptionIsoBmff) {
GenerateKeyRequest(g_key_system, g_key_id, "video/mp4");
VerifyNewKeyResponse(g_license_server, g_client_auth, g_key_id);
}
// TODO(juce): Set up with correct test data.
TEST_F(WvCdmEngineTest, DISABLED_NormalDecryptionWebm) {
GenerateKeyRequest(g_key_system, g_key_id, "video/webm");
VerifyNewKeyResponse(g_license_server, g_client_auth, g_key_id);
}
TEST_F(WvCdmEngineTest, LicenseRenewal) {
GenerateKeyRequest(g_key_system, g_key_id);
GenerateKeyRequest(g_key_system, g_key_id, "video/mp4");
VerifyNewKeyResponse(g_license_server, g_client_auth, g_key_id);
GenerateRenewalRequest(g_key_system, g_key_id);

View File

@@ -74,12 +74,29 @@ TEST(LicenseTestSession, InitNullSession) {
}
// TODO(rfrias): Fix or remove test.
TEST_F(LicenseTest, DISABLED_PrepareKeyRequest) {
TEST_F(LicenseTest, DISABLED_PrepareIsoBmffKeyRequest) {
std::string signed_request;
CdmAppParameterMap app_parameters;
std::string server_url;
CdmSessionId session_id;
license_.PrepareKeyRequest(a2bs_hex(kInitData),
license_.PrepareKeyRequest("video/mp4",
a2bs_hex(kInitData),
kLicenseTypeStreaming,
app_parameters,
session_id,
&signed_request,
&server_url);
EXPECT_EQ(signed_request, a2bs_hex(kSignedRequest));
}
// TODO(rfrias): Fix or remove test.
TEST_F(LicenseTest, DISABLED_PrepareWebmKeyRequest) {
std::string signed_request;
CdmAppParameterMap app_parameters;
std::string server_url;
CdmSessionId session_id;
license_.PrepareKeyRequest("video/webm",
a2bs_hex(kInitData),
kLicenseTypeStreaming,
app_parameters,
session_id,
@@ -94,7 +111,8 @@ TEST_F(LicenseTest, DISABLED_HandleKeyResponseValid) {
CdmAppParameterMap app_parameters;
CdmSessionId session_id;
std::string server_url;
license_.PrepareKeyRequest(a2bs_hex(kInitData),
license_.PrepareKeyRequest("video/mp4",
a2bs_hex(kInitData),
kLicenseTypeStreaming,
app_parameters,
session_id,
@@ -110,7 +128,8 @@ TEST_F(LicenseTest, DISABLED_HandleKeyResponseInvalid) {
CdmAppParameterMap app_parameters;
CdmSessionId session_id;
std::string server_url;
license_.PrepareKeyRequest(a2bs_hex(kInitData),
license_.PrepareKeyRequest("video/mp4",
a2bs_hex(kInitData),
kLicenseTypeStreaming,
app_parameters,
session_id,

View File

@@ -30,6 +30,7 @@ class WvContentDecryptionModule : public TimerHandler {
// Construct a valid license request.
virtual CdmResponseType GenerateKeyRequest(const CdmSessionId& session_id,
const CdmKeySetId& key_set_id,
const std::string& mime_type,
const CdmInitData& init_data,
const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters,

View File

@@ -49,6 +49,7 @@ CdmResponseType WvContentDecryptionModule::CloseSession(
CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
const CdmSessionId& session_id,
const CdmKeySetId& key_set_id,
const std::string& mime_type,
const CdmInitData& init_data,
const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters,
@@ -60,7 +61,7 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
if (sts != NO_ERROR)
return sts;
}
sts = cdm_engine_->GenerateKeyRequest(session_id, key_set_id,
sts = cdm_engine_->GenerateKeyRequest(session_id, key_set_id, mime_type,
init_data, license_type,
app_parameters, key_request,
server_url);

View File

@@ -301,7 +301,8 @@ class WvCdmRequestLicenseTest : public testing::Test {
std::string server_url;
std::string key_set_id;
EXPECT_EQ(wvcdm::KEY_MESSAGE,
decryptor_.GenerateKeyRequest(session_id_, key_set_id, init_data,
decryptor_.GenerateKeyRequest(session_id_, key_set_id,
"video/mp4", init_data,
license_type, app_parameters,
&key_msg_, &server_url));
EXPECT_EQ(0u, server_url.size());
@@ -315,7 +316,8 @@ class WvCdmRequestLicenseTest : public testing::Test {
std::string init_data;
wvcdm::CdmAppParameterMap app_parameters;
EXPECT_EQ(wvcdm::KEY_MESSAGE,
decryptor_.GenerateKeyRequest(session_id_, key_set_id_, init_data,
decryptor_.GenerateKeyRequest(session_id_, key_set_id_,
"video/mp4", init_data,
license_type, app_parameters,
&key_msg_, server_url));
// TODO(edwinwong, rfrias): Add tests cases for when license server url
@@ -329,9 +331,10 @@ class WvCdmRequestLicenseTest : public testing::Test {
wvcdm::CdmAppParameterMap app_parameters;
std::string server_url;
EXPECT_EQ(wvcdm::KEY_MESSAGE,
decryptor_.GenerateKeyRequest(session_id, key_set_id, init_data,
kLicenseTypeRelease, app_parameters,
&key_msg_, &server_url));
decryptor_.GenerateKeyRequest(session_id, key_set_id, "video/mp4",
init_data, kLicenseTypeRelease,
app_parameters, &key_msg_,
&server_url));
}
// Post a request and extract the drm message from the response
@@ -879,12 +882,12 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
wvcdm::CdmAppParameterMap app_parameters;
std::string server_url;
EXPECT_EQ(wvcdm::NEED_PROVISIONING,
decryptor_.GenerateKeyRequest(session_id_, key_set_id, g_key_id,
kLicenseTypeStreaming, app_parameters,
&key_msg_, &server_url));
decryptor_.GenerateKeyRequest(session_id_, key_set_id, "video/mp4",
g_key_id, kLicenseTypeStreaming,
app_parameters, &key_msg_,
&server_url));
EXPECT_EQ(NO_ERROR, decryptor_.GetProvisioningRequest(
&key_msg_, &provisioning_server_url));
&key_msg_, &provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server_url());
response =
GetCertRequestResponse(g_config->provisioning_test_server_url());