Source release v3.0.0-0-g8d3792b-ce + third_party

Change-Id: I399e71ddfffcd436171d1c60283c63ab4658e0b1
This commit is contained in:
Joey Parrish
2015-06-19 15:13:34 -07:00
parent 58aba6b2ec
commit 0546ee6732
965 changed files with 426663 additions and 12897 deletions

View File

@@ -2,10 +2,13 @@
#include <utility>
#include "gtest/gtest.h"
#include <gtest/gtest.h>
#include "log.h"
#include "string_conversions.h"
namespace wvcdm {
namespace {
// Test vectors as suggested by http://tools.ietf.org/html/rfc4648#section-10
@@ -50,9 +53,7 @@ const std::pair<const std::string*, const std::string*> kBase64TestVectors[] = {
make_pair(&kTwoBytesOverData, &kTwoBytesOverB64Data),
make_pair(&kTestData, &kB64TestData)};
} // unnamed namespace
namespace wvcdm {
} // namespace
class Base64EncodeDecodeTest
: public ::testing::TestWithParam<

View File

@@ -4,14 +4,12 @@
// This is because we need a valid RSA certificate, and will attempt to connect
// to the provisioning server to request one if we don't.
#include <errno.h>
#include <getopt.h>
#include <gtest/gtest.h>
#include <string>
#include "cdm_engine.h"
#include "config_test_env.h"
#include "gtest/gtest.h"
#include "initialization_data.h"
#include "license_request.h"
#include "log.h"
@@ -23,6 +21,8 @@
#include "wv_cdm_constants.h"
#include "wv_cdm_types.h"
namespace wvcdm {
namespace {
// Http OK response code.
const int kHttpOk = 200;
@@ -30,29 +30,45 @@ const int kHttpOk = 200;
// Default license server, can be configured using --server command line option
// Default key id (pssh), can be configured using --keyid command line option
std::string g_client_auth;
wvcdm::KeyId g_key_id_pssh;
wvcdm::KeyId g_key_id_unwrapped;
wvcdm::CdmKeySystem g_key_system;
KeyId g_key_id_pssh;
KeyId g_key_id_unwrapped;
CdmKeySystem g_key_system;
std::string g_license_server;
wvcdm::KeyId g_wrong_key_id;
KeyId g_wrong_key_id;
const std::string kCencMimeType = "video/mp4";
const std::string kWebmMimeType = "video/webm";
} // namespace
namespace wvcdm {
class WvCdmEngineTest : public testing::Test {
public:
static void SetUpTestCase() {
ConfigTestEnv config(kContentProtectionServer);
g_client_auth.assign(config.client_auth());
g_key_system.assign(config.key_system());
g_wrong_key_id.assign(config.wrong_key_id());
g_license_server.assign(config.license_server());
g_key_id_pssh.assign(a2bs_hex(config.key_id()));
// Extract the key ID from the PSSH box.
InitializationData extractor(CENC_INIT_DATA_FORMAT,
g_key_id_pssh);
g_key_id_unwrapped = extractor.data();
}
virtual void SetUp() {
CdmResponseType status = cdm_engine_.OpenSession(g_key_system, NULL, &session_id_);
CdmResponseType status =
cdm_engine_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
NULL /* forced_session_id */, &session_id_);
if (status == NEED_PROVISIONING) {
Provision();
status = cdm_engine_.OpenSession(g_key_system, NULL, &session_id_);
status = cdm_engine_.OpenSession(g_key_system, NULL, EMPTY_ORIGIN, NULL,
NULL /* forced_session_id */,
&session_id_);
}
ASSERT_EQ(NO_ERROR, status);
ASSERT_NE("", session_id_) << "Could not open CDM session.";
ASSERT_TRUE(cdm_engine_.IsOpenSession(session_id_));
}
virtual void TearDown() { cdm_engine_.CloseSession(session_id_); }
@@ -64,19 +80,17 @@ class WvCdmEngineTest : public testing::Test {
CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority;
std::string cert, wrapped_key;
ASSERT_EQ(NO_ERROR,
cdm_engine_.GetProvisioningRequest(cert_type,
cert_authority,
&prov_request,
&provisioning_server_url));
ASSERT_EQ(NO_ERROR, cdm_engine_.GetProvisioningRequest(
cert_type, cert_authority, EMPTY_ORIGIN,
&prov_request, &provisioning_server_url));
UrlRequest url_request(provisioning_server_url);
url_request.PostCertRequestInQueryString(prov_request);
std::string message;
bool ok = url_request.GetResponse(&message);
EXPECT_TRUE(ok);
ASSERT_EQ(NO_ERROR,
cdm_engine_.HandleProvisioningResponse(message,
&cert, &wrapped_key));
ASSERT_EQ(NO_ERROR, cdm_engine_.HandleProvisioningResponse(EMPTY_ORIGIN,
message, &cert,
&wrapped_key));
}
void GenerateKeyRequest(const std::string& key_id,
@@ -87,10 +101,12 @@ class WvCdmEngineTest : public testing::Test {
InitializationData init_data(init_data_type_string, key_id);
EXPECT_EQ(KEY_MESSAGE,
cdm_engine_.GenerateKeyRequest(
session_id_, key_set_id, init_data, kLicenseTypeStreaming,
app_parameters, &key_msg_, &server_url, NULL));
CdmKeyRequestType key_request_type;
EXPECT_EQ(KEY_MESSAGE, cdm_engine_.GenerateKeyRequest(
session_id_, key_set_id, init_data,
kLicenseTypeStreaming, app_parameters, &key_msg_,
&key_request_type, &server_url, NULL));
EXPECT_EQ(kKeyRequestTypeInitial, key_request_type);
}
void GenerateRenewalRequest() {
@@ -144,14 +160,14 @@ class WvCdmEngineTest : public testing::Test {
const std::string& client_auth) {
std::string resp = GetKeyRequestResponse(server_url, client_auth);
CdmKeySetId key_set_id;
EXPECT_EQ(wvcdm::KEY_ADDED,
EXPECT_EQ(KEY_ADDED,
cdm_engine_.AddKey(session_id_, resp, &key_set_id));
}
void VerifyRenewalKeyResponse(const std::string& server_url,
const std::string& client_auth) {
std::string resp = GetKeyRequestResponse(server_url, client_auth);
EXPECT_EQ(wvcdm::KEY_ADDED, cdm_engine_.RenewKey(session_id_, resp));
EXPECT_EQ(KEY_ADDED, cdm_engine_.RenewKey(session_id_, resp));
}
CdmEngine cdm_engine_;
@@ -206,94 +222,3 @@ TEST_F(WvCdmEngineTest, LicenseRenewal) {
}
} // namespace wvcdm
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
wvcdm::InitLogging(argc, argv);
wvcdm::ConfigTestEnv config(wvcdm::kContentProtectionServer);
g_client_auth.assign(config.client_auth());
g_key_system.assign(config.key_system());
g_wrong_key_id.assign(config.wrong_key_id());
// The following variables are configurable through command line options.
g_license_server.assign(config.license_server());
g_key_id_pssh.assign(config.key_id());
std::string license_server(g_license_server);
int show_usage = 0;
static const struct option long_options[] = {
{"keyid", required_argument, NULL, 'k'},
{"server", required_argument, NULL, 's'},
{NULL, 0, NULL, '\0'}};
int option_index = 0;
int opt = 0;
while ((opt = getopt_long(argc, argv, "k:s:v", long_options,
&option_index)) != -1) {
switch (opt) {
case 'k': {
g_key_id_pssh.clear();
g_key_id_pssh.assign(optarg);
break;
}
case 's': {
g_license_server.clear();
g_license_server.assign(optarg);
break;
}
case 'v': {
// This option _may_ have already been consumed by wvcdm::InitLogging()
// above, depending on the platform-specific logging implementation.
// We only tell getopt about it so that it is not an error. We ignore
// the option here when seen.
// TODO: Stop passing argv to InitLogging, and instead set the log
// level here through the logging API. We should keep all command-line
// parsing at the application level, rather than split between various
// apps and various platform-specific logging implementations.
break;
}
case '?': {
show_usage = 1;
break;
}
}
}
if (show_usage) {
std::cout << std::endl;
std::cout << "usage: " << argv[0] << " [options]" << std::endl << std::endl;
std::cout << " enclose multiple arguments in '' when using adb shell"
<< std::endl;
std::cout << " e.g. adb shell '" << argv[0] << " --server=\"url\"'"
<< std::endl << std::endl;
std::cout << std::setw(30) << std::left << " --server=<server_url>";
std::cout
<< "configure the license server url, please include http[s] in the url"
<< std::endl;
std::cout << std::setw(30) << std::left << " ";
std::cout << "default: " << license_server << std::endl;
std::cout << std::setw(30) << std::left << " --keyid=<key_id>";
std::cout << "configure the key id or pssh, in hex format" << std::endl;
std::cout << std::setw(30) << std::left << " default keyid:";
std::cout << g_key_id_pssh << std::endl;
return 0;
}
std::cout << std::endl;
std::cout << "Server: " << g_license_server << std::endl;
std::cout << "KeyID: " << g_key_id_pssh << std::endl << std::endl;
g_key_id_pssh = wvcdm::a2bs_hex(g_key_id_pssh);
config.set_license_server(g_license_server);
config.set_key_id(g_key_id_pssh);
// Extract the key ID from the PSSH box.
wvcdm::InitializationData extractor(wvcdm::CENC_INIT_DATA_FORMAT,
g_key_id_pssh);
g_key_id_unwrapped = extractor.data();
return RUN_ALL_TESTS();
}

View File

@@ -1,15 +1,20 @@
// Copyright 2014 Google Inc. All Rights Reserved.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "cdm_session.h"
#include "crypto_key.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "properties.h"
#include "scoped_ptr.h"
#include "string_conversions.h"
#include "test_printers.h"
#include "wv_cdm_constants.h"
namespace wvcdm {
namespace {
const std::string kToken = wvcdm::a2bs_hex(
const std::string kToken = a2bs_hex(
"0AAE02080212107E0A892DEEB021E7AF696B938BB1D5B1188B85AD9D05228E023082010A02"
"82010100DBEDF2BFB0EC98213766E65049B9AB176FA4B1FBFBB2A0C96C87D9F2B895E0ED77"
"93BDA057E6BC3E0CA2348BC6831E03609445CA4D418CB98EAC98FFC87AB2364CE76BA26BEE"
@@ -45,7 +50,7 @@ const std::string kToken = wvcdm::a2bs_hex(
"8CD5A9DF6E3D3A99B806F6D60991358C5BE77117D4F3168F3348E9A048539F892F4D783152"
"C7A8095224AA56B78C5CF7BD1AB1B179C0C0D11E3C3BAC84C141A00191321E3ACC17242E68"
"3C");
const std::string kWrappedKey = wvcdm::a2bs_hex(
const std::string kWrappedKey = a2bs_hex(
"3B84252DD84F1A710365014A114507FFFA3DD404625D61D1EEC7C3A39D72CB8D9318ADE9DA"
"05D69F9776DAFDA49A97BC30E84CA275925DFD98CA04F7DB23465103A224852192DE232902"
"99FF82024F5CCA7716ACA9BE0B56348BA16B9E3136D73789C842CB2ECA4820DDAAF59CCB9B"
@@ -82,9 +87,42 @@ const std::string kWrappedKey = wvcdm::a2bs_hex(
"33EF70621A98184DDAB5E14BC971CF98CF6C91A37FFA83B00AD3BCABBAAB2DEF1C52F43003"
"E74C92B44F9205D22262FB47948654229DE1920F8EDF96A19A88A1CA1552F8856FB4CBF83B"
"AA3348419159D207F65FCE9C1A500C6818");
} // namespace
namespace wvcdm {
const std::string kTestOrigin = "com.google";
class MockDeviceFiles : public DeviceFiles {
public:
MOCK_METHOD1(Init, bool(CdmSecurityLevel));
MOCK_METHOD3(RetrieveCertificate, bool(const std::string&, std::string*,
std::string*));
};
class MockCryptoSession : public CryptoSession {
public:
MOCK_METHOD1(GetToken, bool(std::string*));
MOCK_METHOD0(GetSecurityLevel, CdmSecurityLevel());
MOCK_METHOD0(Open, CdmResponseType());
MOCK_METHOD1(Open, CdmResponseType(SecurityLevel));
MOCK_METHOD1(LoadCertificatePrivateKey, bool(std::string&));
MOCK_METHOD0(DeleteAllUsageReports, CdmResponseType());
};
class MockPolicyEngine : public PolicyEngine {
public:
MockPolicyEngine() : PolicyEngine("mock_session_id", NULL, NULL) {}
// Leaving a place-holder for when PolicyEngine methods need to be mocked
};
class MockCdmLicense : public CdmLicense {
public:
MockCdmLicense(const CdmSessionId& session_id)
: CdmLicense(session_id) {}
MOCK_METHOD3(Init, bool(const std::string&, CryptoSession*, PolicyEngine*));
};
} // namespace
// gmock methods
using ::testing::_;
@@ -95,53 +133,22 @@ using ::testing::SetArgPointee;
using ::testing::Sequence;
using ::testing::StrEq;
class MockDeviceFiles : public DeviceFiles {
public:
MOCK_METHOD1(Init, bool(CdmSecurityLevel));
MOCK_METHOD2(RetrieveCertificate, bool(std::string*, std::string*));
};
class MockCryptoSession : public CryptoSession {
public:
MOCK_METHOD1(GetToken, bool(std::string*));
MOCK_METHOD0(GetSecurityLevel, CdmSecurityLevel());
MOCK_METHOD0(Open, CdmResponseType());
MOCK_METHOD1(Open, CdmResponseType(SecurityLevel));
MOCK_METHOD1(LoadCertificatePrivateKey, bool(std::string&));
};
class MockPolicyEngine : public PolicyEngine {
public:
// Leaving a place holder for when PolicyEngine methods need to be mocked
};
class MockCdmLicense : public CdmLicense {
public:
MOCK_METHOD3(Init, bool(const std::string&, CryptoSession*, PolicyEngine*));
};
class CdmSessionTest : public ::testing::Test {
protected:
virtual void SetUp() {
license_parser_ = new MockCdmLicense();
cdm_session_.reset(new CdmSession(NULL, kTestOrigin, NULL, NULL));
// Inject testing mocks.
license_parser_ = new MockCdmLicense(cdm_session_->session_id());
cdm_session_->set_license_parser(license_parser_);
crypto_session_ = new MockCryptoSession();
cdm_session_->set_crypto_session(crypto_session_);
policy_engine_ = new MockPolicyEngine();
cdm_session_->set_policy_engine(policy_engine_);
file_handle_ = new MockDeviceFiles();
cdm_session_->set_file_handle(file_handle_);
}
virtual void TearDown() {
if (cdm_session_) delete cdm_session_;
}
void CreateSession() { CreateSession(NULL); }
void CreateSession(const CdmClientPropertySet* cdm_client_property_set) {
cdm_session_ =
new CdmSession(license_parser_, crypto_session_, policy_engine_,
file_handle_, cdm_client_property_set);
}
CdmSession* cdm_session_;
scoped_ptr<CdmSession> cdm_session_;
MockCdmLicense* license_parser_;
MockCryptoSession* crypto_session_;
MockPolicyEngine* policy_engine_;
@@ -158,8 +165,9 @@ TEST_F(CdmSessionTest, InitWithCertificate) {
.InSequence(crypto_session_seq)
.WillOnce(Return(level));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(kToken), SetArgPointee<1>(kWrappedKey),
EXPECT_CALL(*file_handle_, RetrieveCertificate(StrEq(kTestOrigin), NotNull(),
NotNull()))
.WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey),
Return(true)));
EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey)))
.InSequence(crypto_session_seq)
@@ -170,7 +178,6 @@ TEST_F(CdmSessionTest, InitWithCertificate) {
Properties::set_use_certificates_as_identification(true);
CreateSession();
ASSERT_EQ(NO_ERROR, cdm_session_->Init());
}
@@ -192,7 +199,6 @@ TEST_F(CdmSessionTest, InitWithKeybox) {
Properties::set_use_certificates_as_identification(false);
CreateSession();
ASSERT_EQ(NO_ERROR, cdm_session_->Init());
}
@@ -206,8 +212,9 @@ TEST_F(CdmSessionTest, ReInitFail) {
.InSequence(crypto_session_seq)
.WillOnce(Return(level));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(kToken), SetArgPointee<1>(kWrappedKey),
EXPECT_CALL(*file_handle_, RetrieveCertificate(StrEq(kTestOrigin), NotNull(),
NotNull()))
.WillOnce(DoAll(SetArgPointee<1>(kToken), SetArgPointee<2>(kWrappedKey),
Return(true)));
EXPECT_CALL(*crypto_session_, LoadCertificatePrivateKey(StrEq(kWrappedKey)))
.InSequence(crypto_session_seq)
@@ -218,9 +225,8 @@ TEST_F(CdmSessionTest, ReInitFail) {
Properties::set_use_certificates_as_identification(true);
CreateSession();
ASSERT_EQ(NO_ERROR, cdm_session_->Init());
ASSERT_EQ(UNKNOWN_ERROR, cdm_session_->Init());
ASSERT_NE(NO_ERROR, cdm_session_->Init());
}
TEST_F(CdmSessionTest, InitFailCryptoError) {
@@ -230,7 +236,6 @@ TEST_F(CdmSessionTest, InitFailCryptoError) {
Properties::set_use_certificates_as_identification(true);
CreateSession();
ASSERT_EQ(UNKNOWN_ERROR, cdm_session_->Init());
}
@@ -244,13 +249,13 @@ TEST_F(CdmSessionTest, InitNeedsProvisioning) {
.InSequence(crypto_session_seq)
.WillOnce(Return(level));
EXPECT_CALL(*file_handle_, Init(Eq(level))).WillOnce(Return(true));
EXPECT_CALL(*file_handle_, RetrieveCertificate(NotNull(), NotNull()))
EXPECT_CALL(*file_handle_, RetrieveCertificate(StrEq(kTestOrigin), NotNull(),
NotNull()))
.WillOnce(Return(false));
Properties::set_use_certificates_as_identification(true);
CreateSession();
ASSERT_EQ(NEED_PROVISIONING, cdm_session_->Init());
}
} // wvcdm
} // namespace wvcdm

View File

@@ -2,10 +2,14 @@
#include "config_test_env.h"
namespace wvcdm {
namespace {
const std::string kWidevineKeySystem = "com.widevine.alpha";
// Content Protection license server data
// Content Protection license server (UAT) data
// For staging server replace url with http://wv-staging-proxy.appspot.com/proxy
const std::string kCpLicenseServer = "http://widevine-proxy.appspot.com/proxy";
const std::string kCpClientAuth = "";
const std::string kCpKeyId =
@@ -26,7 +30,7 @@ const std::string kCpOfflineKeyId =
"00000020" // pssh data size
// pssh data:
"08011a0d7769646576696e655f746573"
"74220d6f66666c696e655f636c697031";
"74220d6f66666c696e655f636c697032";
// Google Play license server data
const std::string kGpLicenseServer =
@@ -72,17 +76,15 @@ const std::string kProductionProvisioningServerUrl =
"certificateprovisioning/v1/devicecertificates/create"
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
const wvcdm::ConfigTestEnv::LicenseServerConfiguration license_servers[] = {
{wvcdm::kGooglePlayServer, kGpLicenseServer, kGpClientAuth, kGpKeyId,
const ConfigTestEnv::LicenseServerConfiguration license_servers[] = {
{kGooglePlayServer, kGpLicenseServer, kGpClientAuth, kGpKeyId,
kGpOfflineKeyId},
{wvcdm::kContentProtectionServer, kCpLicenseServer, kCpClientAuth, kCpKeyId,
{kContentProtectionServer, kCpLicenseServer, kCpClientAuth, kCpKeyId,
kCpOfflineKeyId},
};
} // namespace
namespace wvcdm {
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id) { Init(server_id); }
ConfigTestEnv::ConfigTestEnv(LicenseServerId server_id, bool streaming) {

View File

@@ -59,6 +59,6 @@ class ConfigTestEnv {
CORE_DISALLOW_COPY_AND_ASSIGN(ConfigTestEnv);
};
}; // namespace wvcdm
} // namespace wvcdm
#endif // CDM_TEST_CONFIG_TEST_ENV_H_

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,13 @@
// Copyright 2013 Google Inc. All Rights Reserved.
#include <gtest/gtest.h>
#include "device_files.h"
#include "file_store.h"
#include "gtest/gtest.h"
#include "properties.h"
#include "test_vectors.h"
namespace wvcdm {
namespace {
const std::string kTestDirName = "test_dir";
const std::string kTestFileName = "test.txt";
@@ -14,8 +16,6 @@ const std::string kTestFileNameExt = ".txt";
const std::string kWildcard = "*";
} // namespace
namespace wvcdm {
class FileTest : public testing::Test {
protected:
virtual void SetUp() { CreateTestDir(); }

View File

@@ -16,6 +16,8 @@
#include "log.h"
namespace wvcdm {
namespace {
// Helper function to tokenize a string. This makes it easier to avoid silly
@@ -99,8 +101,6 @@ bool SocketWait(int fd, bool for_read, int timeout_in_ms) {
} // namespace
namespace wvcdm {
// Parses the URL and extracts all relevant information.
// static
bool HttpSocket::ParseUrl(const std::string& url, std::string* scheme,

View File

@@ -51,6 +51,6 @@ class HttpSocket {
CORE_DISALLOW_COPY_AND_ASSIGN(HttpSocket);
};
}; // namespace wvcdm
} // namespace wvcdm
#endif // CDM_TEST_HTTP_SOCKET_H_

View File

@@ -1,13 +1,15 @@
// Copyright 2013 Google Inc. All Rights Reserved.
#include <errno.h>
#include "gtest/gtest.h"
#include <gtest/gtest.h>
#include "http_socket.h"
#include "scoped_ptr.h"
#include "log.h"
#include "scoped_ptr.h"
#include "string_conversions.h"
#include "url_request.h"
namespace wvcdm {
namespace {
// Arbitrary URL for tests.
const std::string kHttpsTestServer("https://www.google.com");
@@ -21,8 +23,6 @@ const int kHttpBufferSize = 4096;
const int kTimeout = 3000;
}
namespace wvcdm {
class HttpSocketTest : public testing::Test {
public:
HttpSocketTest() {}
@@ -159,7 +159,7 @@ ParseUrlTests parse_url_tests[] = {
8888, // port
"/", // path
},
{NULL} // list terminator
{NULL, NULL, false, NULL, 0, NULL} // list terminator
};
TEST_F(HttpSocketTest, ParseUrlTest) {
@@ -204,6 +204,8 @@ TEST_F(HttpSocketTest, RoundTripTest) {
} // namespace wvcdm
int main(int argc, char** argv) {
using namespace wvcdm;
::testing::InitGoogleTest(&argc, argv);
std::string temp;

View File

@@ -0,0 +1,164 @@
// Copyright 2015 Google Inc. All Rights Reserved.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "initialization_data.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
// References:
// [1] http://dashif.org/identifiers/content-protection/
// [2] http://www.w3.org/TR/encrypted-media/cenc-format.html#common-system
namespace wvcdm {
namespace {
const std::string kWidevinePssh = a2bs_hex(
// Widevine PSSH box
"00000042" // atom size
"70737368" // atom type="pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
const std::string kWidevinePsshFirst = a2bs_hex(
// first PSSH box, Widevine
"00000042" // atom size
"70737368" // atom type "pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031"
// second PSSH box, Playready [1]
"00000028" // atom size
"70737368" // atom type "pssh"
"00000000" // v0, flags=0
"9a04f07998404286ab92e65be0885f95" // system id (PlayReady)
"00000008" // data size
// arbitrary data:
"0102030405060708");
const std::string kWidevinePsshAfterV0Pssh = a2bs_hex(
// first PSSH box, Playready [1]
"00000028" // atom size
"70737368" // atom type "pssh"
"00000000" // v0, flags=0
"9a04f07998404286ab92e65be0885f95" // system id (PlayReady)
"00000008" // data size
// arbitrary data:
"0102030405060708"
// second PSSH box, Widevine
"00000042" // atom size
"70737368" // atom type "pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
const std::string kWidevinePsshAfterNonZeroFlags = a2bs_hex(
// first PSSH box, Playready [1]
"00000028" // atom size
"70737368" // atom type "pssh"
"00abcdef" // v0, flags=abcdef
"9a04f07998404286ab92e65be0885f95" // system id (PlayReady)
"00000008" // data size
// arbitrary data:
"0102030405060708"
// second PSSH box, Widevine
"00000042" // atom size
"70737368" // atom type "pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
const std::string kWidevinePsshAfterV1Pssh = a2bs_hex(
// first PSSH box, generic CENC [2]
"00000044" // atom size
"70737368" // atom type "pssh"
"01000000" // v1, flags=0
"1077efecc0b24d02ace33c1e52e2fb4b" // system id (generic CENC)
"00000002" // key ID count
"30313233343536373839303132333435" // key ID="0123456789012345"
"38393031323334354142434445464748" // key ID="ABCDEFGHIJKLMNOP"
"00000000" // data size=0
// second PSSH box, Widevine
"00000042" // atom size
"70737368" // atom type "pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
const std::string kWidevineV1Pssh = a2bs_hex(
// Widevine PSSH box, v1 format
"00000044" // atom size
"70737368" // atom type "pssh"
"01000000" // v1, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000002" // key ID count
"30313233343536373839303132333435" // key ID="0123456789012345"
"38393031323334354142434445464748" // key ID="ABCDEFGHIJKLMNOP"
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
const std::string kOtherBoxFirst = a2bs_hex(
// first box, not a PSSH box
"00000018" // atom size
"77686174" // atom type "what"
"deadbeefdeadbeefdeadbeefdeadbeef" // garbage box data
// second box, a Widevine PSSH box
"00000042" // atom size
"70737368" // atom type "pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
const std::string kZeroSizedPsshBox = a2bs_hex(
// Widevine PSSH box
"00000000" // atom size (whole buffer)
"70737368" // atom type="pssh"
"00000000" // v0, flags=0
"edef8ba979d64acea3c827dcd51d21ed" // system id (Widevine)
"00000022" // data size
// data:
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
class InitializationDataTest : public ::testing::TestWithParam<std::string> {};
} // namespace
TEST_P(InitializationDataTest, Parse) {
InitializationData init_data(ISO_BMFF_VIDEO_MIME_TYPE, GetParam());
EXPECT_FALSE(init_data.IsEmpty());
}
INSTANTIATE_TEST_CASE_P(
ParsePssh, InitializationDataTest,
::testing::Values(
kWidevinePssh,
kWidevinePsshFirst,
kWidevinePsshAfterV0Pssh,
kWidevinePsshAfterNonZeroFlags,
kWidevinePsshAfterV1Pssh,
kWidevineV1Pssh,
kOtherBoxFirst,
kZeroSizedPsshBox
));
} // namespace wvcdm

View File

@@ -5,7 +5,9 @@
namespace wvcdm {
static const std::string kTwoBlankLines("\r\n\r\n");
namespace {
const std::string kTwoBlankLines("\r\n\r\n");
} // namespace
size_t LicenseRequest::FindHeaderEndPosition(
const std::string& response) const {

View File

@@ -25,6 +25,6 @@ class LicenseRequest {
CORE_DISALLOW_COPY_AND_ASSIGN(LicenseRequest);
};
}; // namespace wvcdm
} // namespace wvcdm
#endif // CDM_TEST_LICENSE_REQUEST_H_

View File

@@ -1,36 +1,39 @@
// Copyright 2012 Google Inc. All Rights Reserved.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "clock.h"
#include "crypto_session.h"
#include "license.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "initialization_data.h"
#include "license.h"
#include "policy_engine.h"
#include "properties.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
namespace wvcdm {
namespace {
const uint32_t kAesBlockSize = 16;
const std::string kAesKey = wvcdm::a2bs_hex("000102030405060708090a0b0c0d0e0f");
const std::string kAesIv = wvcdm::a2bs_hex("000102030405060708090a0b0c0d0e0f");
const std::string kCencInitDataHdr = wvcdm::a2bs_hex(
const std::string kAesKey = a2bs_hex("000102030405060708090a0b0c0d0e0f");
const std::string kAesIv = a2bs_hex("000102030405060708090a0b0c0d0e0f");
const std::string kCencInitDataHdr = a2bs_hex(
"00000042" // blob size
"70737368" // "pssh"
"00000000" // flags
"edef8ba979d64acea3c827dcd51d21ed" // Widevine system id
"00000022"); // pssh data size
const std::string kCencPssh = wvcdm::a2bs_hex(
const std::string kCencPssh = a2bs_hex(
"08011a0d7769646576696e655f74657374220f73747265616d696e675f636c697031");
const std::string kCdmSessionId = "sid2";
const std::string kCryptoSessionId = "id2";
const std::string kCryptoRequestId = wvcdm::a2bs_hex(
const std::string kCryptoRequestId = a2bs_hex(
"4341444542353737444337393044394330313030303030303030303030303030");
const uint32_t kNonce = 0x49e81305;
const int64_t kLicenseStartTime = 1413517500; // ~ 01/01/2013
const std::string kToken = wvcdm::a2bs_hex(
const std::string kToken = a2bs_hex(
"0AAE02080212107E0A892DEEB021E7AF696B938BB1D5B1188B85AD9D05228E023082010A02"
"82010100DBEDF2BFB0EC98213766E65049B9AB176FA4B1FBFBB2A0C96C87D9F2B895E0ED77"
"93BDA057E6BC3E0CA2348BC6831E03609445CA4D418CB98EAC98FFC87AB2364CE76BA26BEE"
@@ -66,7 +69,7 @@ const std::string kToken = wvcdm::a2bs_hex(
"8CD5A9DF6E3D3A99B806F6D60991358C5BE77117D4F3168F3348E9A048539F892F4D783152"
"C7A8095224AA56B78C5CF7BD1AB1B179C0C0D11E3C3BAC84C141A00191321E3ACC17242E68"
"3C");
const std::string kLicenseRequestSignature = wvcdm::a2bs_hex(
const std::string kLicenseRequestSignature = a2bs_hex(
"4A560ACFED04787BE0D29D7396234FA2E11D6DD0B22F87FD77AEAEDAA6C8FE54AD9859AE4E"
"C9F12BCB947892D906DAEC1AD78CABD6F9D479CCF91AF5587DB6FC29CBEBF9C338BAF17790"
"90980B1F3333BC901CDBF877490C7B85DB2BF9BC559C98450C6F1E8B2E192959F59CC53BD4"
@@ -74,30 +77,13 @@ const std::string kLicenseRequestSignature = wvcdm::a2bs_hex(
"8D24103EB15C63C227A0D57A9D90F5A409D2D55147EE10A35AE291D2D725C7F161FF827221"
"9AE18B91516E0CDD0B581590DDDEA2A2527E2C9ABA273629B586A9D22D451A827E332CFC3E"
"9BEDB6CF3D8713F9E11675DF1F5DB9038DBBECAB9D1683F8722CAF6E18EC8C04AEE5");
} // namespace
namespace wvcdm {
// Protobuf generated classes
using video_widevine_server::sdk::LicenseRequest_ContentIdentification;
using video_widevine_server::sdk::ClientIdentification;
using video_widevine_server::sdk::LicenseRequest;
using video_widevine_server::sdk::SignedMessage;
// gmock methods
using ::testing::_;
using ::testing::Eq;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::SetArgPointee;
class MockCryptoSession : public CryptoSession {
public:
MOCK_METHOD0(IsOpen, bool());
MOCK_METHOD1(GenerateRequestId, bool(std::string*));
MOCK_METHOD1(UsageInformationSupport, bool(bool*));
MOCK_METHOD2(GetHdcpCapabilities,
bool(OemCryptoHdcpVersion*, OemCryptoHdcpVersion*));
MOCK_METHOD2(GetHdcpCapabilities, bool(HdcpCapability*, HdcpCapability*));
MOCK_METHOD1(GetApiVersion, bool(uint32_t*));
MOCK_METHOD1(GenerateNonce, bool(uint32_t*));
MOCK_METHOD3(PrepareRequest, bool(const std::string&, bool, std::string*));
@@ -105,6 +91,8 @@ class MockCryptoSession : public CryptoSession {
class MockPolicyEngine : public PolicyEngine {
public:
MockPolicyEngine(CryptoSession* crypto)
: PolicyEngine("mock_session_id", NULL, crypto) {}
};
class MockClock : public Clock {
@@ -120,6 +108,21 @@ class MockInitializationData : public InitializationData {
MOCK_METHOD0(is_cenc, bool());
};
} // namespace
// Protobuf generated classes
using video_widevine_server::sdk::LicenseRequest_ContentIdentification;
using video_widevine_server::sdk::ClientIdentification;
using video_widevine_server::sdk::LicenseRequest;
using video_widevine_server::sdk::SignedMessage;
// gmock methods
using ::testing::_;
using ::testing::Eq;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::SetArgPointee;
class CdmLicenseTest : public ::testing::Test {
protected:
virtual void SetUp() {
@@ -127,7 +130,7 @@ class CdmLicenseTest : public ::testing::Test {
crypto_session_ = new MockCryptoSession();
init_data_ = new MockInitializationData(CENC_INIT_DATA_FORMAT,
kCencInitDataHdr + kCencPssh);
policy_engine_ = new MockPolicyEngine();
policy_engine_ = new MockPolicyEngine(crypto_session_);
}
virtual void TearDown() {
@@ -139,7 +142,7 @@ class CdmLicenseTest : public ::testing::Test {
}
void CreateCdmLicense() {
cdm_license_ = new CdmLicense(clock_);
cdm_license_ = new CdmLicense(kCdmSessionId, clock_);
clock_ = NULL;
}
@@ -154,7 +157,7 @@ TEST_F(CdmLicenseTest, InitSuccess) {
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
CreateCdmLicense();
ASSERT_TRUE(cdm_license_->Init(kToken, crypto_session_, policy_engine_));
EXPECT_TRUE(cdm_license_->Init(kToken, crypto_session_, policy_engine_));
}
TEST_F(CdmLicenseTest, InitFail_EmptyToken) {
@@ -176,22 +179,22 @@ TEST_F(CdmLicenseTest, InitFail_PolicyEngineNull) {
TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
bool usage_information_support = true;
CryptoSession::OemCryptoHdcpVersion current_hdcp_version =
CryptoSession::kOemCryptoNoHdcpDeviceAttached;
CryptoSession::OemCryptoHdcpVersion max_hdcp_version =
CryptoSession::kOemCryptoHdcpVersion2_1;
CryptoSession::HdcpCapability current_hdcp_version = HDCP_NO_DIGITAL_OUTPUT;
CryptoSession::HdcpCapability max_hdcp_version = HDCP_V2_1;
uint32_t crypto_session_api_version = 9;
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
EXPECT_CALL(*crypto_session_, GenerateRequestId(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(kCryptoRequestId), Return(true)));
EXPECT_CALL(*crypto_session_, UsageInformationSupport(NotNull())).WillOnce(
DoAll(SetArgPointee<0>(usage_information_support), Return(true)));
EXPECT_CALL(*crypto_session_, UsageInformationSupport(NotNull()))
.WillOnce(
DoAll(SetArgPointee<0>(usage_information_support), Return(true)));
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(current_hdcp_version),
SetArgPointee<1>(max_hdcp_version), Return(true)));
EXPECT_CALL(*crypto_session_, GetApiVersion(NotNull())).WillOnce(
DoAll(SetArgPointee<0>(crypto_session_api_version), Return(true)));
EXPECT_CALL(*crypto_session_, GetApiVersion(NotNull()))
.WillOnce(
DoAll(SetArgPointee<0>(crypto_session_api_version), Return(true)));
EXPECT_CALL(*clock_, GetCurrentTime()).WillOnce(Return(kLicenseStartTime));
EXPECT_CALL(*crypto_session_, GenerateNonce(NotNull()))
.WillOnce(DoAll(SetArgPointee<0>(kNonce), Return(true)));
@@ -207,7 +210,7 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
Properties::set_use_certificates_as_identification(true);
std::string server_url;
EXPECT_TRUE(cdm_license_->PrepareKeyRequest(
*init_data_, kLicenseTypeStreaming, app_parameters, kCdmSessionId,
*init_data_, kLicenseTypeStreaming, app_parameters,
&signed_request, &server_url));
EXPECT_TRUE(!signed_request.empty());
@@ -279,4 +282,5 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
license_request.protocol_version());
EXPECT_EQ(kNonce, license_request.key_control_nonce());
}
}
} // namespace wvcdm

View File

@@ -0,0 +1,323 @@
// Copyright 2012 Google Inc. All Rights Reserved.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "crypto_session.h"
#include "license.h"
#include "max_res_engine.h"
#include "mock_clock.h"
#include "scoped_ptr.h"
#include "wv_cdm_types.h"
namespace wvcdm {
typedef ::video_widevine_server::sdk::License License;
typedef ::video_widevine_server::sdk::License::KeyContainer KeyContainer;
typedef ::video_widevine_server::sdk::License::KeyContainer::OutputProtection
OutputProtection;
typedef ::video_widevine_server::sdk::License::KeyContainer::
VideoResolutionConstraint VideoResolutionConstraint;
typedef ::google::protobuf::RepeatedPtrField<KeyContainer> KeyList;
typedef ::google::protobuf::RepeatedPtrField<VideoResolutionConstraint>
ConstraintList;
using namespace testing;
namespace {
const KeyId kKeyId1 = "357adc89f1673433c36c621f1b5c41ee";
const KeyId kKeyId2 = "3d25f819250789ecfc9ed48cc99af164";
const KeyId kKeyId3 = "fe3cf6b69e76c9a1c877922e1a661707";
const KeyId kKeyId4 = "29a321b9886658078f916fdd41d6f570";
const KeyId kKeyId5 = "cc5b031bcde371031c06822d935b9a63";
const KeyId kKeyId6 = "90ac1332e4efc8acbaf929c8d321f50c";
const uint32_t kMinRes1 = 0;
const uint32_t kMaxRes1 = 2000;
const uint32_t kTargetRes1 = (kMinRes1 + kMaxRes1) / 2;
const uint32_t kMinRes2 = kMaxRes1;
const uint32_t kMaxRes2 = 4000;
const uint32_t kTargetRes2 = (kMinRes2 + kMaxRes2) / 2;
const uint32_t kTargetRes3 = kMaxRes2 + 1000;
const OutputProtection::HDCP kHdcpDefault = OutputProtection::HDCP_V2;
const OutputProtection::HDCP kHdcpConstraint = OutputProtection::HDCP_V2_1;
const int64_t kHdcpInterval = 10;
class HdcpOnlyMockCryptoSession : public CryptoSession {
public:
MOCK_METHOD2(GetHdcpCapabilities, bool(HdcpCapability*, HdcpCapability*));
};
} // namespace
ACTION_P2(IncrementAndReturnPointee, p, a) {
*p += a;
return *p;
}
class MaxResEngineTest : public Test {
protected:
virtual void SetUp() {
mock_clock_ = new NiceMock<MockClock>();
current_time_ = 0;
ON_CALL(*mock_clock_, GetCurrentTime())
.WillByDefault(
IncrementAndReturnPointee(&current_time_, kHdcpInterval));
max_res_engine_.reset(new MaxResEngine(&crypto_session_, mock_clock_));
KeyList* keys = license_.mutable_key();
// Key 1 - Content key w/ ID, no HDCP, no constraints
{
KeyContainer* key1 = keys->Add();
key1->set_type(KeyContainer::CONTENT);
key1->set_id(kKeyId1);
}
// Key 2 - Content key w/ ID, HDCP, no constraints
{
KeyContainer* key2 = keys->Add();
key2->set_type(KeyContainer::CONTENT);
key2->set_id(kKeyId2);
key2->mutable_required_protection()->set_hdcp(kHdcpDefault);
}
// Key 3 - Content key w/ ID, no HDCP, constraints
{
KeyContainer* key3 = keys->Add();
key3->set_type(KeyContainer::CONTENT);
key3->set_id(kKeyId3);
AddConstraints(key3->mutable_video_resolution_constraints());
}
// Key 4 - Content key w/ ID, HDCP, constraints
{
KeyContainer* key4 = keys->Add();
key4->set_type(KeyContainer::CONTENT);
key4->set_id(kKeyId4);
key4->mutable_required_protection()->set_hdcp(kHdcpDefault);
AddConstraints(key4->mutable_video_resolution_constraints());
}
// Key 5 - Content key w/o ID, HDCP, constraints
{
KeyContainer* key5 = keys->Add();
key5->set_type(KeyContainer::CONTENT);
key5->mutable_required_protection()->set_hdcp(kHdcpDefault);
AddConstraints(key5->mutable_video_resolution_constraints());
}
// Key 6 - Non-content key
{
KeyContainer* key6 = keys->Add();
key6->set_type(KeyContainer::OPERATOR_SESSION);
}
}
void AddConstraints(ConstraintList* constraints) {
// Constraint 1 - Low-res and no HDCP
{
VideoResolutionConstraint* constraint1 = constraints->Add();
constraint1->set_min_resolution_pixels(kMinRes1);
constraint1->set_max_resolution_pixels(kMaxRes1);
}
// Constraint 2 - High-res and stricter HDCP
{
VideoResolutionConstraint* constraint2 = constraints->Add();
constraint2->set_min_resolution_pixels(kMinRes2);
constraint2->set_max_resolution_pixels(kMaxRes2);
constraint2->mutable_required_protection()->set_hdcp(kHdcpConstraint);
}
}
MockClock* mock_clock_;
int64_t current_time_;
StrictMock<HdcpOnlyMockCryptoSession> crypto_session_;
scoped_ptr<MaxResEngine> max_res_engine_;
License license_;
};
TEST_F(MaxResEngineTest, IsPermissiveByDefault) {
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
}
TEST_F(MaxResEngineTest, IsPermissiveWithoutALicense) {
max_res_engine_->SetResolution(1, kTargetRes1);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
}
TEST_F(MaxResEngineTest, IsPermissiveWithoutAResolution) {
max_res_engine_->SetLicense(license_);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
}
TEST_F(MaxResEngineTest, HandlesResolutionsBasedOnConstraints) {
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NO_DIGITAL_OUTPUT),
Return(true)));
max_res_engine_->SetLicense(license_);
max_res_engine_->SetResolution(1, kTargetRes1);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
max_res_engine_->SetResolution(1, kTargetRes2);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
max_res_engine_->SetResolution(1, kTargetRes3);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_FALSE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_FALSE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
}
TEST_F(MaxResEngineTest, RequestsHdcpImmediatelyAndOnlyAfterInterval) {
int64_t start_time = current_time_;
{
InSequence calls;
EXPECT_CALL(*mock_clock_, GetCurrentTime()).WillOnce(Return(start_time));
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
.WillOnce(
DoAll(SetArgPointee<0>(HDCP_V2_2),
Return(true)));
EXPECT_CALL(*mock_clock_, GetCurrentTime())
.WillOnce(Return(start_time + kHdcpInterval / 2))
.WillOnce(Return(start_time + kHdcpInterval));
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
.WillOnce(
DoAll(SetArgPointee<0>(HDCP_V2_2),
Return(true)));
}
max_res_engine_->SetLicense(license_);
max_res_engine_->SetResolution(1, kTargetRes1);
max_res_engine_->OnTimerEvent();
max_res_engine_->OnTimerEvent();
max_res_engine_->OnTimerEvent();
}
TEST_F(MaxResEngineTest, DoesNotRequestHdcpWithoutALicense) {
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)).Times(0);
max_res_engine_->OnTimerEvent();
}
TEST_F(MaxResEngineTest, HandlesConstraintOverridingHdcp) {
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_V2),
Return(true)));
max_res_engine_->SetLicense(license_);
max_res_engine_->SetResolution(1, kTargetRes1);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
max_res_engine_->SetResolution(1, kTargetRes2);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_FALSE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_FALSE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
}
TEST_F(MaxResEngineTest, HandlesNoHdcp) {
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _))
.WillRepeatedly(
DoAll(SetArgPointee<0>(HDCP_NONE),
Return(true)));
max_res_engine_->SetLicense(license_);
max_res_engine_->SetResolution(1, kTargetRes1);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_FALSE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
max_res_engine_->SetResolution(1, kTargetRes2);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_FALSE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_FALSE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
}
TEST_F(MaxResEngineTest, IgnoresHdcpWithoutAResolution) {
EXPECT_CALL(crypto_session_, GetHdcpCapabilities(_, _)).Times(0);
max_res_engine_->SetLicense(license_);
max_res_engine_->OnTimerEvent();
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId1));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId2));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId3));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId4));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId5));
EXPECT_TRUE(max_res_engine_->CanDecrypt(kKeyId6));
}
} // wvcdm

18
core/test/mock_clock.h Normal file
View File

@@ -0,0 +1,18 @@
// Copyright 2014 Google Inc. All Rights Reserved.
#ifndef CDM_TEST_MOCK_CLOCK_H_
#define CDM_TEST_MOCK_CLOCK_H_
#include "clock.h"
#include <gmock/gmock.h>
namespace wvcdm {
class MockClock : public Clock {
public:
MOCK_METHOD0(GetCurrentTime, int64_t());
};
} // wvcdm
#endif // CDM_TEST_MOCK_CLOCK_H_

File diff suppressed because it is too large Load Diff

View File

@@ -7,87 +7,386 @@
namespace wvcdm {
void PrintTo(const enum CdmResponseType& value, ::std::ostream* os) {
switch(value) {
case NO_ERROR: *os << "NO_ERROR";
switch (value) {
case NO_ERROR: *os << "NO_ERROR";
break;
case UNKNOWN_ERROR: *os << "UNKNOWN_ERROR";
case UNKNOWN_ERROR: *os << "UNKNOWN_ERROR";
break;
case KEY_ADDED: *os << "KEY_ADDED";
case KEY_ADDED: *os << "KEY_ADDED";
break;
case KEY_ERROR: *os << "KEY_ERROR";
case KEY_ERROR: *os << "KEY_ERROR";
break;
case KEY_MESSAGE: *os << "KEY_MESSAGE";
case KEY_MESSAGE: *os << "KEY_MESSAGE";
break;
case NEED_KEY: *os << "NEED_KEY";
case NEED_KEY: *os << "NEED_KEY";
break;
case KEY_CANCELED: *os << "KEY_CANCELED";
case KEY_CANCELED: *os << "KEY_CANCELED";
break;
case NEED_PROVISIONING: *os << "NEED_PROVISIONING";
case NEED_PROVISIONING: *os << "NEED_PROVISIONING";
break;
case DEVICE_REVOKED: *os << "DEVICE_REVOKED";
case DEVICE_REVOKED: *os << "DEVICE_REVOKED";
break;
case INSUFFICIENT_CRYPTO_RESOURCES: *os << "INSUFFICIENT_CRYPTO_RESOURCES";
case INSUFFICIENT_CRYPTO_RESOURCES: *os << "INSUFFICIENT_CRYPTO_RESOURCES";
break;
case ADD_KEY_ERROR: *os << "ADD_KEY_ERROR";
break;
case CERT_PROVISIONING_GET_KEYBOX_ERROR_1: *os << "CERT_PROVISIONING_GET_KEYBOX_ERROR_1";
break;
case CERT_PROVISIONING_GET_KEYBOX_ERROR_2: *os << "CERT_PROVISIONING_GET_KEYBOX_ERROR_2";
break;
case CERT_PROVISIONING_INVALID_CERT_TYPE: *os << "CERT_PROVISIONING_INVALID_CERT_TYPE";
break;
case CERT_PROVISIONING_REQUEST_ERROR_1: *os << "CERT_PROVISIONING_REQUEST_ERROR_1";
break;
case CERT_PROVISIONING_REQUEST_ERROR_2: *os << "CERT_PROVISIONING_REQUEST_ERROR_2";
break;
case CERT_PROVISIONING_REQUEST_ERROR_3: *os << "CERT_PROVISIONING_REQUEST_ERROR_3";
break;
case CERT_PROVISIONING_REQUEST_ERROR_4: *os << "CERT_PROVISIONING_REQUEST_ERROR_4";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_1: *os << "CERT_PROVISIONING_RESPONSE_ERROR_1";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_2: *os << "CERT_PROVISIONING_RESPONSE_ERROR_2";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_3: *os << "CERT_PROVISIONING_RESPONSE_ERROR_3";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_4: *os << "CERT_PROVISIONING_RESPONSE_ERROR_4";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_5: *os << "CERT_PROVISIONING_RESPONSE_ERROR_5";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_6: *os << "CERT_PROVISIONING_RESPONSE_ERROR_6";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_7: *os << "CERT_PROVISIONING_RESPONSE_ERROR_7";
break;
case CERT_PROVISIONING_RESPONSE_ERROR_8: *os << "CERT_PROVISIONING_RESPONSE_ERROR_8";
break;
case CRYPTO_SESSION_OPEN_ERROR_1: *os << "CRYPTO_SESSION_OPEN_ERROR_1";
break;
case CRYPTO_SESSION_OPEN_ERROR_2: *os << "CRYPTO_SESSION_OPEN_ERROR_2";
break;
case CRYPTO_SESSION_OPEN_ERROR_3: *os << "CRYPTO_SESSION_OPEN_ERROR_3";
break;
case CRYPTO_SESSION_OPEN_ERROR_4: *os << "CRYPTO_SESSION_OPEN_ERROR_4";
break;
case CRYPTO_SESSION_OPEN_ERROR_5: *os << "CRYPTO_SESSION_OPEN_ERROR_5";
break;
case DECRYPT_NOT_READY: *os << "DECRYPT_NOT_READY";
break;
case DEVICE_CERTIFICATE_ERROR_1: *os << "DEVICE_CERTIFICATE_ERROR_1";
break;
case DEVICE_CERTIFICATE_ERROR_2: *os << "DEVICE_CERTIFICATE_ERROR_2";
break;
case DEVICE_CERTIFICATE_ERROR_3: *os << "DEVICE_CERTIFICATE_ERROR_3";
break;
case DEVICE_CERTIFICATE_ERROR_4: *os << "DEVICE_CERTIFICATE_ERROR_4";
break;
case EMPTY_KEY_DATA_1: *os << "EMPTY_KEY_DATA_1";
break;
case EMPTY_KEY_DATA_2: *os << "EMPTY_KEY_DATA_2";
break;
case EMPTY_KEYSET_ID: *os << "EMPTY_KEYSET_ID";
break;
case EMPTY_KEYSET_ID_ENG_1: *os << "EMPTY_KEYSET_ID_ENG_1";
break;
case EMPTY_KEYSET_ID_ENG_2: *os << "EMPTY_KEYSET_ID_ENG_2";
break;
case EMPTY_KEYSET_ID_ENG_3: *os << "EMPTY_KEYSET_ID_ENG_3";
break;
case EMPTY_KEYSET_ID_ENG_4: *os << "EMPTY_KEYSET_ID_ENG_4";
break;
case EMPTY_LICENSE_RENEWAL: *os << "EMPTY_LICENSE_RENEWAL";
break;
case EMPTY_LICENSE_RESPONSE_1: *os << "EMPTY_LICENSE_RESPONSE_1";
break;
case EMPTY_LICENSE_RESPONSE_2: *os << "EMPTY_LICENSE_RESPONSE_2";
break;
case EMPTY_PROVISIONING_CERTIFICATE: *os << "EMPTY_PROVISIONING_CERTIFICATE";
break;
case EMPTY_PROVISIONING_RESPONSE: *os << "EMPTY_PROVISIONING_RESPONSE";
break;
case EMPTY_SESSION_ID: *os << "EMPTY_SESSION_ID";
break;
case GENERATE_DERIVED_KEYS_ERROR: *os << "GENERATE_DERIVED_KEYS_ERROR";
break;
case LICENSE_RENEWAL_NONCE_GENERATION_ERROR: *os << "LICENSE_RENEWAL_NONCE_GENERATION_ERROR";
break;
case GENERATE_USAGE_REPORT_ERROR: *os << "GENERATE_USAGE_REPORT_ERROR";
break;
case GET_LICENSE_ERROR: *os << "GET_LICENSE_ERROR";
break;
case GET_RELEASED_LICENSE_ERROR: *os << "GET_RELEASED_LICENSE_ERROR";
break;
case GET_USAGE_INFO_ERROR_1: *os << "GET_USAGE_INFO_ERROR_1";
break;
case GET_USAGE_INFO_ERROR_2: *os << "GET_USAGE_INFO_ERROR_2";
break;
case GET_USAGE_INFO_ERROR_3: *os << "GET_USAGE_INFO_ERROR_3";
break;
case GET_USAGE_INFO_ERROR_4: *os << "GET_USAGE_INFO_ERROR_4";
break;
case INIT_DATA_NOT_FOUND: *os << "INIT_DATA_NOT_FOUND";
break;
case INVALID_CRYPTO_SESSION_1: *os << "INVALID_CRYPTO_SESSION_1";
break;
case INVALID_CRYPTO_SESSION_2: *os << "INVALID_CRYPTO_SESSION_2";
break;
case INVALID_CRYPTO_SESSION_3: *os << "INVALID_CRYPTO_SESSION_3";
break;
case INVALID_CRYPTO_SESSION_4: *os << "INVALID_CRYPTO_SESSION_4";
break;
case INVALID_CRYPTO_SESSION_5: *os << "INVALID_CRYPTO_SESSION_5";
break;
case INVALID_DECRYPT_PARAMETERS_ENG_1: *os << "INVALID_DECRYPT_PARAMETERS_ENG_1";
break;
case INVALID_DECRYPT_PARAMETERS_ENG_2: *os << "INVALID_DECRYPT_PARAMETERS_ENG_2";
break;
case INVALID_DECRYPT_PARAMETERS_ENG_3: *os << "INVALID_DECRYPT_PARAMETERS_ENG_3";
break;
case INVALID_DECRYPT_PARAMETERS_ENG_4: *os << "INVALID_DECRYPT_PARAMETERS_ENG_4";
break;
case INVALID_DEVICE_CERTIFICATE_TYPE: *os << "INVALID_DEVICE_CERTIFICATE_TYPE";
break;
case INVALID_KEY_SYSTEM: *os << "INVALID_KEY_SYSTEM";
break;
case INVALID_LICENSE_RESPONSE: *os << "INVALID_LICENSE_RESPONSE";
break;
case INVALID_LICENSE_TYPE: *os << "INVALID_LICENSE_TYPE";
break;
case INVALID_PARAMETERS_ENG_1: *os << "INVALID_PARAMETERS_ENG_1";
break;
case INVALID_PARAMETERS_ENG_2: *os << "INVALID_PARAMETERS_ENG_2";
break;
case INVALID_PARAMETERS_ENG_3: *os << "INVALID_PARAMETERS_ENG_3";
break;
case INVALID_PARAMETERS_ENG_4: *os << "INVALID_PARAMETERS_ENG_4";
break;
case INVALID_PARAMETERS_LIC_1: *os << "INVALID_PARAMETERS_LIC_1";
break;
case INVALID_PARAMETERS_LIC_2: *os << "INVALID_PARAMETERS_LIC_2";
break;
case INVALID_PROVISIONING_PARAMETERS_1: *os << "INVALID_PROVISIONING_PARAMETERS_1";
break;
case INVALID_PROVISIONING_PARAMETERS_2: *os << "INVALID_PROVISIONING_PARAMETERS_2";
break;
case INVALID_PROVISIONING_REQUEST_PARAM_1: *os << "INVALID_PROVISIONING_REQUEST_PARAM_1";
break;
case INVALID_PROVISIONING_REQUEST_PARAM_2: *os << "INVALID_PROVISIONING_REQUEST_PARAM_2";
break;
case INVALID_QUERY_KEY: *os << "INVALID_QUERY_KEY";
break;
case INVALID_SESSION_ID: *os << "INVALID_SESSION_ID";
break;
case KEY_REQUEST_ERROR_1: *os << "KEY_REQUEST_ERROR_1";
break;
case KEY_SIZE_ERROR: *os << "KEY_SIZE_ERROR";
break;
case KEYSET_ID_NOT_FOUND_1: *os << "KEYSET_ID_NOT_FOUND_1";
break;
case KEYSET_ID_NOT_FOUND_2: *os << "KEYSET_ID_NOT_FOUND_2";
break;
case KEYSET_ID_NOT_FOUND_3: *os << "KEYSET_ID_NOT_FOUND_3";
break;
case LICENSE_ID_NOT_FOUND: *os << "LICENSE_ID_NOT_FOUND";
break;
case LICENSE_PARSER_INIT_ERROR: *os << "LICENSE_PARSER_INIT_ERROR";
break;
case LICENSE_PARSER_NOT_INITIALIZED_1: *os << "LICENSE_PARSER_NOT_INITIALIZED_1";
break;
case LICENSE_PARSER_NOT_INITIALIZED_2: *os << "LICENSE_PARSER_NOT_INITIALIZED_2";
break;
case LICENSE_PARSER_NOT_INITIALIZED_3: *os << "LICENSE_PARSER_NOT_INITIALIZED_3";
break;
case LICENSE_RESPONSE_NOT_SIGNED: *os << "LICENSE_RESPONSE_NOT_SIGNED";
break;
break;
case LICENSE_RESPONSE_PARSE_ERROR_1: *os << "LICENSE_RESPONSE_PARSE_ERROR_1";
break;
case LICENSE_RESPONSE_PARSE_ERROR_2: *os << "LICENSE_RESPONSE_PARSE_ERROR_2";
break;
case LICENSE_RESPONSE_PARSE_ERROR_3: *os << "LICENSE_RESPONSE_PARSE_ERROR_3";
break;
case LOAD_KEY_ERROR: *os << "LOAD_KEY_ERROR";
break;
case NO_CONTENT_KEY: *os << "NO_CONTENT_KEY";
break;
case REFRESH_KEYS_ERROR: *os << "REFRESH_KEYS_ERROR";
break;
case RELEASE_ALL_USAGE_INFO_ERROR_1: *os << "RELEASE_ALL_USAGE_INFO_ERROR_1";
break;
case RELEASE_ALL_USAGE_INFO_ERROR_2: *os << "RELEASE_ALL_USAGE_INFO_ERROR_2";
break;
case RELEASE_KEY_ERROR: *os << "RELEASE_KEY_ERROR";
break;
case RELEASE_KEY_REQUEST_ERROR: *os << "RELEASE_KEY_REQUEST_ERROR";
break;
case RELEASE_LICENSE_ERROR_1: *os << "RELEASE_LICENSE_ERROR_1";
break;
case RELEASE_LICENSE_ERROR_2: *os << "RELEASE_LICENSE_ERROR_2";
break;
case RELEASE_USAGE_INFO_ERROR: *os << "RELEASE_USAGE_INFO_ERROR";
break;
case RENEW_KEY_ERROR_1: *os << "RENEW_KEY_ERROR_1";
break;
case RENEW_KEY_ERROR_2: *os << "RENEW_KEY_ERROR_2";
break;
case LICENSE_RENEWAL_SIGNING_ERROR: *os << "LICENSE_RENEWAL_SIGNING_ERROR";
break;
case RESTORE_OFFLINE_LICENSE_ERROR_1: *os << "RESTORE_OFFLINE_LICENSE_ERROR_1";
break;
case RESTORE_OFFLINE_LICENSE_ERROR_2: *os << "RESTORE_OFFLINE_LICENSE_ERROR_2";
break;
case SESSION_INIT_ERROR_1: *os << "SESSION_INIT_ERROR_1";
break;
case SESSION_INIT_ERROR_2: *os << "SESSION_INIT_ERROR_2";
break;
case SESSION_INIT_GET_KEYBOX_ERROR: *os << "SESSION_INIT_GET_KEYBOX_ERROR";
break;
case SESSION_NOT_FOUND_1: *os << "SESSION_NOT_FOUND_1";
break;
case SESSION_NOT_FOUND_2: *os << "SESSION_NOT_FOUND_2";
break;
case SESSION_NOT_FOUND_3: *os << "SESSION_NOT_FOUND_3";
break;
case SESSION_NOT_FOUND_4: *os << "SESSION_NOT_FOUND_4";
break;
case SESSION_NOT_FOUND_5: *os << "SESSION_NOT_FOUND_5";
break;
case SESSION_NOT_FOUND_6: *os << "SESSION_NOT_FOUND_6";
break;
case SESSION_NOT_FOUND_7: *os << "SESSION_NOT_FOUND_7";
break;
case SESSION_NOT_FOUND_8: *os << "SESSION_NOT_FOUND_8";
break;
case SESSION_NOT_FOUND_9: *os << "SESSION_NOT_FOUND_9";
break;
case SESSION_NOT_FOUND_10: *os << "SESSION_NOT_FOUND_10";
break;
case SESSION_NOT_FOUND_FOR_DECRYPT: *os << "SESSION_NOT_FOUND_FOR_DECRYPT";
break;
case SESSION_KEYS_NOT_FOUND: *os << "SESSION_KEYS_NOT_FOUND";
break;
case SIGNATURE_NOT_FOUND: *os << "SIGNATURE_NOT_FOUND";
break;
case STORE_LICENSE_ERROR_1: *os << "STORE_LICENSE_ERROR_1";
break;
case STORE_LICENSE_ERROR_2: *os << "STORE_LICENSE_ERROR_2";
break;
case STORE_LICENSE_ERROR_3: *os << "STORE_LICENSE_ERROR_3";
break;
case STORE_USAGE_INFO_ERROR: *os << "STORE_USAGE_INFO_ERROR";
break;
case UNPROVISION_ERROR_1: *os << "UNPROVISION_ERROR_1";
break;
case UNPROVISION_ERROR_2: *os << "UNPROVISION_ERROR_2";
break;
case UNPROVISION_ERROR_3: *os << "UNPROVISION_ERROR_3";
break;
case UNPROVISION_ERROR_4: *os << "UNPROVISION_ERROR_4";
break;
case UNSUPPORTED_INIT_DATA: *os << "UNSUPPORTED_INIT_DATA";
break;
case USAGE_INFO_NOT_FOUND: *os << "USAGE_INFO_NOT_FOUND";
break;
case LICENSE_RENEWAL_SERVICE_CERTIFICATE_GENERATION_ERROR:
*os << "LICENSE_RENEWAL_SERVICE_CERTIFICATE_GENERATION_ERROR";
break;
case EMPTY_PROVISIONING_CERTIFICATE_2: *os << "EMPTY_PROVISIONING_CERTIFICATE_2";
break;
case PARSE_SERVICE_CERTIFICATE_ERROR: *os << "PARSE_SERVICE_CERTIFICATE_ERROR";
break;
case SERVICE_CERTIFICATE_TYPE_ERROR: *os << "SERVICE_CERTIFICATE_TYPE_ERROR";
break;
case CLIENT_ID_GENERATE_RANDOM_ERROR: *os << "CLIENT_ID_GENERATE_RANDOM_ERROR";
break;
case CLIENT_ID_AES_INIT_ERROR: *os << "CLIENT_ID_AES_INIT_ERROR";
break;
case CLIENT_ID_AES_ENCRYPT_ERROR: *os << "CLIENT_ID_AES_ENCRYPT_ERROR";
break;
case CLIENT_ID_RSA_INIT_ERROR: *os << "CLIENT_ID_RSA_INIT_ERROR";
break;
case CLIENT_ID_RSA_ENCRYPT_ERROR: *os << "CLIENT_ID_RSA_ENCRYPT_ERROR";
break;
case INVALID_QUERY_STATUS: *os << "INVALID_QUERY_STATUS";
break;
case LICENSE_PARSER_NOT_INITIALIZED_4: *os << "LICENSE_PARSER_NOT_INITIALIZED_4";
break;
case INVALID_PARAMETERS_LIC_3: *os << "INVALID_PARAMETERS_LIC_3";
break;
case INVALID_PARAMETERS_LIC_4: *os << "INVALID_PARAMETERS_LIC_4";
break;
case INVALID_PARAMETERS_LIC_6: *os << "INVALID_PARAMETERS_LIC_6";
break;
case INVALID_PARAMETERS_LIC_7: *os << "INVALID_PARAMETERS_LIC_7";
break;
case LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR:
*os << "LICENSE_REQUEST_SERVICE_CERTIFICATE_GENERATION_ERROR";
break;
case CENC_INIT_DATA_UNAVAILABLE: *os << "CENC_INIT_DATA_UNAVAILABLE";
break;
case PREPARE_CENC_CONTENT_ID_FAILED: *os << "PREPARE_CENC_CONTENT_ID_FAILED";
break;
case WEBM_INIT_DATA_UNAVAILABLE: *os << "WEBM_INIT_DATA_UNAVAILABLE";
break;
case PREPARE_WEBM_CONTENT_ID_FAILED: *os << "PREPARE_WEBM_CONTENT_ID_FAILED";
break;
case UNSUPPORTED_INIT_DATA_FORMAT: *os << "UNSUPPORTED_INIT_DATA_FORMAT";
break;
case LICENSE_REQUEST_NONCE_GENERATION_ERROR: *os << "LICENSE_REQUEST_NONCE_GENERATION_ERROR";
break;
case LICENSE_REQUEST_SIGNING_ERROR: *os << "LICENSE_REQUEST_SIGNING_ERROR";
break;
case EMPTY_LICENSE_REQUEST: *os << "EMPTY_LICENSE_REQUEST";
break;
default:
*os << "Unknown CdmResponseType";
*os << "Unknown CdmResponseType";
break;
}
}
void PrintTo(const enum CdmEventType& value, ::std::ostream* os) {
switch(value) {
case LICENSE_EXPIRED_EVENT: *os << "LICENSE_EXPIRED_EVENT";
break;
case LICENSE_RENEWAL_NEEDED_EVENT: *os << "LICENSE_RENEWAL_NEEDED_EVENT";
break;
default:
*os << "Unknown CdmEventType";
break;
}
};
void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os) {
switch(value) {
case kLicenseTypeOffline: *os << "kLicenseTypeOffline";
switch (value) {
case kLicenseTypeOffline: *os << "kLicenseTypeOffline";
break;
case kLicenseTypeStreaming: *os << "kLicenseTypeStreaming";
case kLicenseTypeStreaming: *os << "kLicenseTypeStreaming";
break;
case kLicenseTypeRelease: *os << "kLicenseTypeRelease";
case kLicenseTypeRelease: *os << "kLicenseTypeRelease";
break;
case kLicenseTypeDeferred: *os << "kLicenseTypeDeferred";
break;
default:
*os << "Unknown CdmLicenseType";
*os << "Unknown CdmLicenseType";
break;
}
};
void PrintTo(const enum CdmSecurityLevel& value, ::std::ostream* os) {
switch(value) {
case kSecurityLevelUninitialized: *os << "kSecurityLevelUninitialized";
switch (value) {
case kSecurityLevelUninitialized: *os << "kSecurityLevelUninitialized";
break;
case kSecurityLevelL1: *os << "kSecurityLevelL1";
case kSecurityLevelL1: *os << "kSecurityLevelL1";
break;
case kSecurityLevelL2: *os << "kSecurityLevelL2";
case kSecurityLevelL2: *os << "kSecurityLevelL2";
break;
case kSecurityLevelL3: *os << "kSecurityLevelL3";
case kSecurityLevelL3: *os << "kSecurityLevelL3";
break;
case kSecurityLevelUnknown: *os << "kSecurityLevelUnknown";
case kSecurityLevelUnknown: *os << "kSecurityLevelUnknown";
break;
default:
*os << "Unknown CdmSecurityLevel";
*os << "Unknown CdmSecurityLevel";
break;
}
};
void PrintTo(const enum CdmCertificateType& value, ::std::ostream* os) {
switch(value) {
case kCertificateWidevine: *os << "kCertificateWidevine";
switch (value) {
case kCertificateWidevine: *os << "kCertificateWidevine";
break;
case kCertificateX509: *os << "kCertificateX509";
case kCertificateX509: *os << "kCertificateX509";
break;
default:
*os << "Unknown CdmCertificateType";
*os << "Unknown CdmCertificateType";
break;
}
};
}; // namespace wvcdm
} // namespace wvcdm

View File

@@ -10,10 +10,9 @@
namespace wvcdm {
void PrintTo(const enum CdmResponseType& value, ::std::ostream* os);
void PrintTo(const enum CdmEventType& value, ::std::ostream* os);
void PrintTo(const enum CdmLicenseType& value, ::std::ostream* os);
void PrintTo(const enum CdmSecurityLevel& value, ::std::ostream* os);
void PrintTo(const enum CdmCertificateType& value, ::std::ostream* os);
}; // namespace wvcdm
} // namespace wvcdm
#endif // CDM_TEST_PRINTERS_H_

View File

@@ -1,51 +0,0 @@
// Copyright 2013 Google Inc. All Rights Reserved.
#include "gtest/gtest.h"
#include "timer.h"
namespace wvcdm {
class TestTimerHandler : public TimerHandler {
public:
TestTimerHandler() : timer_events_(0) {};
virtual ~TestTimerHandler() {};
virtual void OnTimerEvent() { timer_events_++; }
uint32_t timer_events() { return timer_events_; }
void ResetTimerEvents() { timer_events_ = 0; }
private:
uint32_t timer_events_;
};
TEST(TimerTest, ParametersCheck) {
Timer timer;
EXPECT_FALSE(timer.Start(NULL, 10));
TestTimerHandler handler;
EXPECT_FALSE(timer.Start(&handler, 0));
}
TEST(TimerTest, TimerCheck) {
TestTimerHandler handler;
Timer timer;
uint32_t duration = 10;
EXPECT_EQ(0u, handler.timer_events());
EXPECT_FALSE(timer.IsRunning());
EXPECT_TRUE(timer.Start(&handler, 1));
EXPECT_TRUE(timer.IsRunning());
sleep(duration);
EXPECT_LE(duration - 1, handler.timer_events());
EXPECT_LE(handler.timer_events(), duration + 1);
timer.Stop();
EXPECT_FALSE(timer.IsRunning());
sleep(duration);
EXPECT_LE(duration - 1, handler.timer_events());
EXPECT_LE(handler.timer_events(), duration + 1);
}
}

View File

@@ -9,6 +9,8 @@
#include "log.h"
#include "string_conversions.h"
namespace wvcdm {
namespace {
const int kReadBufferSize = 1024;
@@ -69,8 +71,6 @@ void ConcatenateChunkedResponse(const std::string http_response,
} // namespace
namespace wvcdm {
UrlRequest::UrlRequest(const std::string& url)
: is_connected_(false), socket_(url) {
Reconnect();
@@ -78,7 +78,7 @@ UrlRequest::UrlRequest(const std::string& url)
UrlRequest::~UrlRequest() {}
bool UrlRequest::Reconnect() {
void UrlRequest::Reconnect() {
socket_.CloseSocket();
if (socket_.Connect(kConnectTimeoutMs)) {
is_connected_ = true;
@@ -109,7 +109,7 @@ bool UrlRequest::GetResponse(std::string* message) {
}
ConcatenateChunkedResponse(response, message);
LOGD("HTTP response: (%d): %s", message->size(), b2a_hex(*message).c_str());
LOGV("HTTP response: (%d): %s", message->size(), b2a_hex(*message).c_str());
return true;
}
@@ -154,7 +154,7 @@ bool UrlRequest::PostRequestWithPath(const std::string& path,
request.append(data);
int ret = socket_.Write(request.c_str(), request.size(), kWriteTimeoutMs);
LOGD("HTTP request: (%d): %s", request.size(), b2a_hex(request).c_str());
LOGV("HTTP request: (%d): %s", request.size(), b2a_hex(request).c_str());
return ret != -1;
}

View File

@@ -17,7 +17,7 @@ class UrlRequest {
~UrlRequest();
bool is_connected() const { return is_connected_; }
bool Reconnect();
void Reconnect();
bool PostRequest(const std::string& data);
bool PostCertRequestInQueryString(const std::string& data);
@@ -34,6 +34,6 @@ class UrlRequest {
CORE_DISALLOW_COPY_AND_ASSIGN(UrlRequest);
};
}; // namespace wvcdm
} // namespace wvcdm
#endif // CDM_TEST_URL_REQUEST_H_