Common test main

Merge from Widevine repo of http://go/wvgerrit/56521

This CL adds a common main routine for integration tests.  It sets a
default test configuration for the provisioning and license server
urls and certificates, and allows the user to set them on the command
line.

Test: current unit tests still pass.
Bug: 72354901 Fix Generic Crypto tests.
Change-Id: I604a3d9e15d50da5041794624c4571c0dcb091f5
This commit is contained in:
Fred Gylys-Colwell
2018-08-03 17:09:19 -07:00
parent 4af5aaf18a
commit e635d4d384
11 changed files with 707 additions and 772 deletions

View File

@@ -39,6 +39,7 @@ namespace {
// Http OK response code.
const int kHttpOk = 200;
// TODO(fredgc): Move these to test_base.cpp in next CL.
// 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;

View File

@@ -260,14 +260,17 @@ const std::string kGpClientOfflineReleaseQueryParameters =
const ConfigTestEnv::LicenseServerConfiguration license_servers[] = {
{kGooglePlayServer, kGpLicenseServer, "", kGpClientAuth, kGpKeyId,
kGpOfflineKeyId, kCpProductionProvisioningServerUrl, ""},
{kContentProtectionUatServer, kCpUatLicenseServer, kCpUatServiceCertificate,
kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
// TODO(rfrias): replace when b/62880305 is addressed. For now use production
kCpProductionProvisioningServerUrl,
kCpProductionProvisioningServiceCertificate},
{kContentProtectionStagingServer, kCpStagingLicenseServer,
kCpStagingServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
kCpStagingProvisioningServerUrl, kCpStagingProvisioningServiceCertificate},
{kContentProtectionProductionServer, kCpProductionLicenseServer,
kCpProductionServiceCertificate, kCpClientAuth, kCpKeyId, kCpOfflineKeyId,
kCpProductionProvisioningServerUrl,
@@ -303,7 +306,21 @@ ConfigTestEnv::ConfigTestEnv(ServerConfigurationId server_id, bool streaming,
}
}
ConfigTestEnv& ConfigTestEnv::operator=(const ConfigTestEnv &other) {
this->server_id_ = other.server_id_;
this->client_auth_ = other.client_auth_;
this->key_id_ = other.key_id_;
this->key_system_ = other.key_system_;
this->license_server_ = other.license_server_;
this->provisioning_server_ = other.provisioning_server_;
this->license_service_certificate_ = other.license_service_certificate_;
this->provisioning_service_certificate_ =
other.provisioning_service_certificate_;
return *this;
}
void ConfigTestEnv::Init(ServerConfigurationId server_id) {
this->server_id_ = server_id;
client_auth_ = license_servers[server_id].client_tag;
key_id_ = license_servers[server_id].key_id;
key_system_ = kWidevineKeySystem;

View File

@@ -49,20 +49,25 @@ class ConfigTestEnv {
typedef struct {
ServerConfigurationId id;
std::string license_server_url;
std::string license_service_certificate;
std::string license_service_certificate; // Binary (not hex).
std::string client_tag;
std::string key_id;
std::string key_id; // Hex.
std::string offline_key_id;
std::string provisioning_server_url;
std::string provisioning_service_certificate;
std::string provisioning_service_certificate; // Binary (not hex).
} LicenseServerConfiguration;
explicit ConfigTestEnv(ServerConfigurationId server_id);
ConfigTestEnv(ServerConfigurationId server_id, bool streaming);
ConfigTestEnv(ServerConfigurationId server_id, bool streaming, bool renew,
bool release);
// Allow copy and assign. Performance is not an issue in test initialization.
ConfigTestEnv(const ConfigTestEnv &other) { *this = other; };
ConfigTestEnv& operator=(const ConfigTestEnv &other);
~ConfigTestEnv() {};
ServerConfigurationId server_id() { return server_id_; }
const std::string& client_auth() const { return client_auth_; }
const KeyId& key_id() const { return key_id_; }
const CdmKeySystem& key_system() const { return key_system_; }
@@ -88,13 +93,22 @@ class ConfigTestEnv {
void set_license_server(std::string& license_server) {
license_server_.assign(license_server);
}
void set_license_service_certificate(
std::string& license_service_certificate) {
license_service_certificate_.assign(license_service_certificate);
}
void set_provisioning_server(std::string& provisioning_server) {
provisioning_server_.assign(provisioning_server);
}
void set_provisioning_service_certificate(
std::string& provisioning_service_certificate) {
provisioning_service_certificate_.assign(provisioning_service_certificate);
}
private:
void Init(ServerConfigurationId server_id);
ServerConfigurationId server_id_;
std::string client_auth_;
KeyId key_id_;
CdmKeySystem key_system_;
@@ -102,8 +116,6 @@ class ConfigTestEnv {
std::string provisioning_server_;
std::string license_service_certificate_;
std::string provisioning_service_certificate_;
CORE_DISALLOW_COPY_AND_ASSIGN(ConfigTestEnv);
};
} // namespace wvcdm

View File

@@ -24,6 +24,74 @@
#include "url_request.h"
namespace wvcdm {
namespace {
void show_menu(char* prog_name) {
std::cout << std::endl;
std::cout << "usage: " << prog_name << " [options]" << std::endl << std::endl;
std::cout << " enclose multiple arguments in '' when using adb shell"
<< std::endl;
std::cout << " e.g. adb shell '" << prog_name << " --server=\"url\"'"
<< std::endl;
std::cout << " or adb shell '" << prog_name << " -u\"url\"'" << std::endl
<< std::endl;
std::cout << " -v/--verbose" << std::endl;
std::cout << " increase logging verbosity (may be repeated)" << std::endl
<< std::endl;
std::cout << " -f/--no_filter" << std::endl;
std::cout << " Do not filter out inappropriate tests" << std::endl
<< std::endl;
std::cout << " -c/--cast" << std::endl;
std::cout << " Run tests appropriate for a Cast Receiver" << std::endl
<< std::endl;
std::cout << " -i/--license_server_id=<gp/cp/st>" << std::endl;
std::cout << " specifies which default server settings to use: "
<< std::endl;
std::cout << " gp for GooglePlay server" << std::endl;
std::cout << " cp for Content Protection UAT server" << std::endl;
std::cout << " st for Content Protection Staging server" << std::endl
<< std::endl;
std::cout << " -k/--keyid=<key_id>" << std::endl;
std::cout << " configure the key id or pssh, in hex format" << std::endl
<< std::endl;
std::cout << " -s/--service_certificate=<cert>" << std::endl;
std::cout << " configure the signed license service certificate" << std::endl;
std::cout << " Specify the SignedDeviceCertificate (from "
<< "device_certificate.proto) " << std::endl;
std::cout << " in hex format." << std::endl;
std::cout << " Due to the length of the argument use, " << std::endl;
std::cout << " echo \"/system/bin/request_license_test -s \\\""
<< "0ABF02...A29914\\\"\" \\" << std::endl;
std::cout << " > run_request_license_test.sh" << std::endl;
std::cout << " chmod +x run_request_license_test.sh" << std::endl;
std::cout << " adb push run_request_license_test.sh /system/bin"
<< std::endl;
std::cout << " adb shell sh /system/bin/run_request_license_test.sh"
<< std::endl << std::endl;
std::cout << " -S/--provisioning_certificate=<cert>" << std::endl;
std::cout << " configure the signed provisioning service certificate" << std::endl
<< " in hex" << std::endl << std::endl;
std::cout << " -u/--license_server_url=<url>" << std::endl;
std::cout << " configure the license server url, please include http[s]"
<< " in the url" << std::endl
<< std::endl;
std::cout << " -p/--provisioning_server_url=<url>" << std::endl;
std::cout << " configure the provisioning server url, please include http[s]"
<< " in the url" << std::endl
<< std::endl;
}
} // namespace
ConfigTestEnv WvCdmTestBase::default_config_(kContentProtectionUatServer);
TestCryptoSession::TestCryptoSession(metrics::CryptoMetrics* crypto_metrics)
: CryptoSession(crypto_metrics) {
@@ -79,4 +147,113 @@ void WvCdmTestBase::InstallTestRootOfTrust() {
}
}
bool WvCdmTestBase::Initialize(int argc, char **argv) {
Properties::Init();
bool is_cast_receiver = false;
bool force_load_test_keybox = false; // TODO(fredgc): obsolete. remove.
bool filter_tests = true;
bool show_usage = false;
static const struct option long_options[] = {
{"license_server_id", required_argument, NULL, 'i'},
{"keyid", required_argument, NULL, 'k'},
{"service_certificate", required_argument, NULL, 's'},
{"provisioning_certificate", required_argument, NULL, 'S'},
{"license_server_url", required_argument, NULL, 'u'},
{"provisioning_server_url", required_argument, NULL, 'p'},
{"cast", no_argument, NULL, 'c'},
{"no_filter", no_argument, NULL, 'f'},
{"verbose", no_argument, NULL, 'v'},
{NULL, 0, NULL, '\0'}};
int option_index = 0;
int opt = 0;
int verbosity = 0;
while ((opt = getopt_long(argc, argv, "i:k:s:S:u:p:cfv", long_options,
&option_index)) != -1) {
switch (opt) {
case 'i': {
std::string license_id(optarg);
if (!license_id.compare("gp")) {
default_config_ = ConfigTestEnv(kGooglePlayServer);
} else if (!license_id.compare("cp")) {
default_config_ = ConfigTestEnv(kContentProtectionUatServer);
} else if (!license_id.compare("st")) {
default_config_ = ConfigTestEnv(kContentProtectionStagingServer);
} else {
std::cout << "Invalid license server id" << optarg << std::endl;
show_usage = true;
}
break;
}
case 'k': {
std::string key_id(optarg);
default_config_.set_key_id(key_id);
break;
}
case 's': {
std::string certificate(a2bs_hex(optarg));
default_config_.set_license_service_certificate(certificate);
break;
}
case 'S': {
std::string certificate(a2bs_hex(optarg));
default_config_.set_provisioning_service_certificate(certificate);
break;
}
case 'u': {
std::string server(optarg);
default_config_.set_license_server(server);
break;
}
case 'p': {
std::string server(optarg);
default_config_.set_provisioning_server(server);
break;
}
case 'c': {
is_cast_receiver = true;
break;
}
case 'f': {
filter_tests = false;
break;
}
case 'v': {
++verbosity;
break;
}
case '?': {
show_usage = true;
break;
}
}
}
if (show_usage) {
show_menu(argv[0]);
return false;
}
g_cutoff = static_cast<LogPriority>(verbosity);
// Displays server url, port and key Id being used
std::cout << std::endl;
std::cout << "Default Server: " << default_config_.license_server()
<< std::endl;
std::cout << "Default KeyID: " << default_config_.key_id() << std::endl
<< std::endl;
// Figure out which tests are appropriate for OEMCrypto, based on features
// supported.
wvoec::global_features.Initialize(is_cast_receiver, force_load_test_keybox);
// If the user requests --no_filter, we don't change the filter, otherwise, we
// filter out features that are not supported.
if (filter_tests) {
::testing::GTEST_FLAG(filter) =
wvoec::global_features.RestrictFilter(::testing::GTEST_FLAG(filter));
}
return true;
}
} // namespace wvcdm

View File

@@ -10,18 +10,32 @@
#include "config_test_env.h"
#include "crypto_session.h"
#include "metrics_collections.h"
#include "string_conversions.h"
namespace wvcdm {
// This is the base class for Widevine CDM integration tests. It's main use is
// to configure OEMCrypto to use a test keybox.
class WvCdmTestBase : public ::testing::Test {
public:
WvCdmTestBase() {}
WvCdmTestBase() : config_(default_config_) {}
virtual ~WvCdmTestBase() {}
virtual void SetUp();
virtual std::string binary_key_id() const { return a2bs_hex(config_.key_id()); }
// Returns true if the test program should continue, if false, the caller
// should exit. This should be called by main() to allow the user to pass in
// command line switches.
static bool Initialize(int argc, char **argv);
// Install a test keybox, if appropriate.
static void InstallTestRootOfTrust();
// The default test configuration. This is influenced by command line
// arguments before any tests are created.
static ConfigTestEnv default_config_;
// Configuration for an individual test. This is initialized to be the
// default configuration, but can be modified by the test itself.
ConfigTestEnv config_;
};
class TestCryptoSession : public CryptoSession {

View File

@@ -0,0 +1,17 @@
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
// Use in place of the gtest_main in order to initialize the WvCdmTestBase using
// command line parameters.
#include <stdio.h>
#include "log.h"
#include "test_base.h"
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
if (!wvcdm::WvCdmTestBase::Initialize(argc, argv)) return 0;
return RUN_ALL_TESTS();
}

View File

@@ -3,6 +3,11 @@
#
LOCAL_PATH := $(call my-dir)
# Integration tests have a special main that does some initialization and
# takes some command line arguments to set the default license server. The
# variable test_main is used to indicate an extra file with the main
# routine.
test_name := base64_test
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
@@ -11,21 +16,25 @@ test_name := buffer_reader_test
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_name := cdm_feature_test
test_src_dir := .
include $(LOCAL_PATH)/unit-test.mk
test_name := cdm_engine_test
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := cdm_extended_duration_test
test_src_dir := .
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := cdm_feature_test
test_src_dir := .
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := cdm_session_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := counter_metric_unittest
test_src_dir := ../metrics/test
@@ -33,7 +42,8 @@ include $(LOCAL_PATH)/unit-test.mk
test_name := crypto_session_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := device_files_unittest
test_src_dir := ../core/test
@@ -55,45 +65,61 @@ test_name := file_utils_unittest
test_src_dir := .
include $(LOCAL_PATH)/unit-test.mk
# TODO(fredgc): Fix in later CL.
# test_name := generic_crypto_unittest
# test_src_dir := ../core/test
# test_main := ../core/test/test_main.cpp
# include $(LOCAL_PATH)/integration-test.mk
test_name := http_socket_test
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_main :=
include $(LOCAL_PATH)/integration-test.mk
test_name := initialization_data_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_name := license_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_name := license_keys_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_name := policy_engine_unittest
test_name := license_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := policy_engine_constraints_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := policy_engine_unittest
test_src_dir := ../core/test
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := request_license_test
test_src_dir := .
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := service_certificate_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_name := shared_ptr_test
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_name := timer_unittest
test_src_dir := .
include $(LOCAL_PATH)/unit-test.mk
test_name := usage_table_header_unittest
test_src_dir := ../core/test
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name := value_metric_unittest
test_src_dir := ../metrics/test
@@ -101,7 +127,8 @@ include $(LOCAL_PATH)/unit-test.mk
test_name := wv_cdm_metrics_test
test_src_dir := .
include $(LOCAL_PATH)/unit-test.mk
test_main := ../core/test/test_main.cpp
include $(LOCAL_PATH)/integration-test.mk
test_name :=
test_src_dir :=

View File

@@ -9,6 +9,8 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <utils/Thread.h>
#include "OEMCryptoCENC.h"
#include "cdm_identifier.h"
#include "clock.h"
#include "config_test_env.h"
@@ -18,13 +20,12 @@
#include "license_request.h"
#include "log.h"
#include "oemcrypto_adapter.h"
#include "OEMCryptoCENC.h"
#include "properties.h"
#include "pst_report.h"
#include "string_conversions.h"
#include "test_base.h"
#include "test_printers.h"
#include "url_request.h"
#include <utils/Thread.h>
#include "wv_cdm_constants.h"
#include "wv_content_decryption_module.h"
@@ -42,16 +43,6 @@ const uint32_t kClockTolerance = 10;
const uint32_t kMaxUsageTableSize = 50;
const std::string kEmptyServiceCertificate;
// 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::ConfigTestEnv* g_config = NULL;
wvcdm::KeyId g_key_id;
wvcdm::CdmKeySystem g_key_system;
std::string g_license_server;
wvcdm::ServerConfigurationId g_license_server_id =
wvcdm::kContentProtectionUatServer;
// TODO(rfrias): refactor to print out the decryption test names
struct SubSampleInfo {
bool retrieve_key;
@@ -67,6 +58,7 @@ struct SubSampleInfo {
uint8_t subsample_flags;
};
// clang-format off
SubSampleInfo kEncryptedStreamingNoPstSubSample = {
// key SD, encrypted, 256b
true, 1, true, true, false,
@@ -177,6 +169,7 @@ std::string kOfflineClip4 = wvcdm::a2bs_hex(
"EDEF8BA979D64ACEA3C827DCD51D21ED00000020" // Widevine system id
"08011a0d7769646576696e655f74657374220d6f" // pssh data
"66666c696e655f636c697034");
// clang-format off
std::string kUatLicenseServer = "https://proxy.uat.widevine.com/proxy";
@@ -202,10 +195,10 @@ using ::testing::StrNe;
namespace wvcdm {
// Protobuf generated classes
using video_widevine::ClientIdentification;
using video_widevine::LicenseIdentification;
using video_widevine::LicenseRequest_ContentIdentification;
using video_widevine::LicenseRequest_ContentIdentification_CencDeprecated;
using video_widevine::ClientIdentification;
using video_widevine::SignedMessage;
class TestWvCdmClientPropertySet : public CdmClientPropertySet {
@@ -261,16 +254,16 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
protected:
void GetOfflineConfiguration(std::string* key_id, std::string* client_auth) {
ConfigTestEnv config(g_license_server_id, false);
if (g_key_id.compare(a2bs_hex(g_config->key_id())) == 0)
ConfigTestEnv config(config_.server_id(), false);
if (config_.key_id().compare(a2bs_hex(config_.key_id())) == 0)
key_id->assign(a2bs_hex(config.key_id()));
else
key_id->assign(g_key_id);
key_id->assign(config_.key_id());
if (g_client_auth.compare(g_config->client_auth()) == 0)
if (config_.client_auth().compare(config_.client_auth()) == 0)
client_auth->assign(config.client_auth());
else
client_auth->assign(g_client_auth);
client_auth->assign(config_.client_auth());
}
void GenerateKeyRequest(const std::string& init_data,
@@ -449,9 +442,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
}
void Provision() {
CdmResponseType status =
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
CdmResponseType status = decryptor_.OpenSession(
config_.key_system(), NULL, kDefaultCdmIdentifier, NULL, &session_id_);
switch (status) {
case NO_ERROR:
decryptor_.CloseSession(session_id_);
@@ -472,10 +464,10 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
kEmptyServiceCertificate, &key_msg_, &provisioning_server_url);
EXPECT_EQ(NO_ERROR, status);
if (NO_ERROR != status) return;
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server());
EXPECT_EQ(provisioning_server_url, config_.provisioning_server());
std::string response =
GetCertRequestResponse(g_config->provisioning_server());
GetCertRequestResponse(config_.provisioning_server());
EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(NO_ERROR,
decryptor_.HandleProvisioningResponse(kDefaultCdmIdentifier, response,
@@ -547,13 +539,11 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
EXPECT_EQ(::video_widevine::LicenseRequest_RequestType_RENEWAL,
license_renewal.type());
EXPECT_LT(0, license_renewal.request_time());
EXPECT_EQ(video_widevine::VERSION_2_1,
license_renewal.protocol_version());
EXPECT_EQ(video_widevine::VERSION_2_1, license_renewal.protocol_version());
EXPECT_TRUE(license_renewal.has_key_control_nonce());
}
void ValidateReleaseRequest(std::string& usage_msg,
bool license_used,
void ValidateReleaseRequest(std::string& usage_msg, bool license_used,
int64_t expected_seconds_since_license_received,
int64_t expected_seconds_since_first_playback,
int64_t expected_seconds_since_last_playback) {
@@ -592,22 +582,21 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
EXPECT_TRUE(!existing_license.session_usage_table_entry().empty());
// Verify usage report
uint8_t *buffer = reinterpret_cast<uint8_t *>(
const_cast<char *>(existing_license.session_usage_table_entry().data()));
uint8_t* buffer = reinterpret_cast<uint8_t*>(
const_cast<char*>(existing_license.session_usage_table_entry().data()));
Unpacked_PST_Report usage_report(buffer);
EXPECT_EQ(usage_report.report_size(),
existing_license.session_usage_table_entry().size());
EXPECT_EQ(license_used ? kInactiveUsed : kInactiveUnused,
usage_report.status());
EXPECT_EQ(id.provider_session_token().size(),
usage_report.pst_length());
std::string pst(reinterpret_cast<char *>(usage_report.pst()),
EXPECT_EQ(id.provider_session_token().size(), usage_report.pst_length());
std::string pst(reinterpret_cast<char*>(usage_report.pst()),
usage_report.pst_length());
EXPECT_EQ(id.provider_session_token(), pst);
EXPECT_LE(kInsecureClock, usage_report.clock_security_level());
int64_t seconds_since_license_received
= usage_report.seconds_since_license_received();
int64_t seconds_since_license_received =
usage_report.seconds_since_license_received();
int64_t seconds_since_first_decrypt =
usage_report.seconds_since_first_decrypt();
int64_t seconds_since_last_decrypt =
@@ -631,13 +620,12 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
EXPECT_EQ(::video_widevine::LicenseRequest_RequestType_RELEASE,
license_renewal.type());
EXPECT_LT(0, license_renewal.request_time());
EXPECT_EQ(video_widevine::VERSION_2_1,
license_renewal.protocol_version());
EXPECT_EQ(video_widevine::VERSION_2_1, license_renewal.protocol_version());
EXPECT_TRUE(license_renewal.has_key_control_nonce());
}
void ValidateHasUpdateUsageEntry(const drm_metrics::WvCdmMetrics& metrics)
const {
void ValidateHasUpdateUsageEntry(
const drm_metrics::WvCdmMetrics& metrics) const {
bool has_update_usage_entry_metrics = false;
for (const auto& session : metrics.session_metrics()) {
has_update_usage_entry_metrics |=
@@ -675,10 +663,10 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
}
std::string key = QUERY_KEY_LICENSE_DURATION_REMAINING;
ASSERT_THAT(query_info, Contains(Pair(key,StrNe(""))));
ASSERT_THAT(query_info, Contains(Pair(key, StrNe(""))));
EXPECT_TRUE(StringToInt64(query_info[key], license_duration_remaining));
key = QUERY_KEY_PLAYBACK_DURATION_REMAINING;
ASSERT_THAT(query_info, Contains(Pair(key,StrNe(""))));
ASSERT_THAT(query_info, Contains(Pair(key, StrNe(""))));
EXPECT_TRUE(StringToInt64(query_info[key], playback_duration_remaining));
}
@@ -696,8 +684,8 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
}
std::string GetSecurityLevel(TestWvCdmClientPropertySet* property_set) {
decryptor_.OpenSession(g_key_system, property_set, kDefaultCdmIdentifier,
NULL, &session_id_);
decryptor_.OpenSession(config_.key_system(), property_set,
kDefaultCdmIdentifier, NULL, &session_id_);
CdmQueryMap query_info;
EXPECT_EQ(NO_ERROR,
decryptor_.QuerySessionStatus(session_id_, &query_info));
@@ -767,9 +755,9 @@ class WvCdmExtendedDurationTest : public WvCdmTestBase {
TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) {
Provision();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(config_.key_id(), kLicenseTypeStreaming);
EXPECT_TRUE(!key_msg_.empty());
@@ -786,14 +774,14 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) {
// Verify Client Identification
const ClientIdentification& client_id = license_request.client_id();
EXPECT_EQ(video_widevine::
ClientIdentification_TokenType_DRM_DEVICE_CERTIFICATE,
EXPECT_EQ(
video_widevine::ClientIdentification_TokenType_DRM_DEVICE_CERTIFICATE,
client_id.type());
EXPECT_LT(0, client_id.client_info_size());
for (int i = 0; i < client_id.client_info_size(); ++i) {
const ::video_widevine::ClientIdentification_NameValue&
name_value = client_id.client_info(i);
const ::video_widevine::ClientIdentification_NameValue& name_value =
client_id.client_info(i);
EXPECT_TRUE(!name_value.name().empty());
EXPECT_TRUE(!name_value.value().empty());
}
@@ -819,7 +807,7 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) {
const LicenseRequest_ContentIdentification_CencDeprecated& cenc_id =
content_id.cenc_id_deprecated();
EXPECT_TRUE(std::equal(cenc_id.pssh(0).begin(), cenc_id.pssh(0).end(),
g_key_id.begin() + 32));
config_.key_id().begin() + 32));
EXPECT_EQ(video_widevine::STREAMING, cenc_id.license_type());
EXPECT_TRUE(cenc_id.has_request_id());
@@ -827,8 +815,7 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) {
EXPECT_EQ(::video_widevine::LicenseRequest_RequestType_NEW,
license_request.type());
EXPECT_LT(0, license_request.request_time());
EXPECT_EQ(video_widevine::VERSION_2_1,
license_request.protocol_version());
EXPECT_EQ(video_widevine::VERSION_2_1, license_request.protocol_version());
EXPECT_TRUE(license_request.has_key_control_nonce());
decryptor_.CloseSession(session_id_);
@@ -836,10 +823,11 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRequestTest) {
TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRenewalTest) {
Provision();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(config_.key_id(), kLicenseTypeStreaming);
VerifyKeyRequestResponse(config_.license_server(), config_.client_auth(),
false);
// Validate signed response
SignedMessage signed_message;
@@ -903,8 +891,7 @@ TEST_F(WvCdmExtendedDurationTest, VerifyLicenseRenewalTest) {
EXPECT_EQ(::video_widevine::LicenseRequest_RequestType_RENEWAL,
license_renewal.type());
EXPECT_LT(0, license_renewal.request_time());
EXPECT_EQ(video_widevine::VERSION_2_1,
license_renewal.protocol_version());
EXPECT_EQ(video_widevine::VERSION_2_1, license_renewal.protocol_version());
EXPECT_TRUE(license_renewal.has_key_control_nonce());
decryptor_.CloseSession(session_id_);
@@ -916,22 +903,23 @@ TEST_F(WvCdmExtendedDurationTest, DecryptionCloseSessionConcurrencyTest) {
// Leave session open to avoid CDM termination
CdmSessionId session_id;
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id);
// Retrieve offline license
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(kOfflineClip2PstInitData, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
VerifyKeyRequestResponse(config_.license_server(), config_.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_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id_));
CdmResponseType status = NO_ERROR;
@@ -995,12 +983,11 @@ TEST_F(WvCdmExtendedDurationTest, DISABLED_UsageOverflowTest) {
EXPECT_TRUE(handle.Init(security_level));
std::vector<std::string> provider_session_tokens;
EXPECT_TRUE(handle.DeleteAllUsageInfoForApp(
DeviceFiles::GetUsageInfoFileName(""),
&provider_session_tokens));
DeviceFiles::GetUsageInfoFileName(""), &provider_session_tokens));
for (size_t i = 0; i < kMaxUsageTableSize + 100; ++i) {
decryptor_.OpenSession(g_key_system, property_set, kDefaultCdmIdentifier,
NULL, &session_id_);
decryptor_.OpenSession(config_.key_system(), property_set,
kDefaultCdmIdentifier, NULL, &session_id_);
std::string key_id = a2bs_hex(
"000000427073736800000000" // blob size and pssh
"EDEF8BA979D64ACEA3C827DCD51D21ED00000022" // Widevine system id
@@ -1008,30 +995,35 @@ TEST_F(WvCdmExtendedDurationTest, DISABLED_UsageOverflowTest) {
"747265616d696e675f636c697035");
GenerateKeyRequest(key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
VerifyKeyRequestResponse(config_.license_server(), config_.client_auth(),
false);
decryptor_.CloseSession(session_id_);
}
CdmUsageInfo usage_info;
CdmUsageInfoReleaseMessage release_msg;
CdmResponseType status = decryptor_.GetUsageInfo(
"", kDefaultCdmIdentifier, &usage_info);
CdmResponseType status =
decryptor_.GetUsageInfo("", kDefaultCdmIdentifier, &usage_info);
EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status);
int error_count = 0;
while (usage_info.size() > 0) {
for (size_t i = 0; i < usage_info.size(); ++i) {
release_msg =
GetUsageInfoResponse(g_license_server, g_client_auth, usage_info[i]);
EXPECT_EQ(NO_ERROR, decryptor_.ReleaseUsageInfo(release_msg,
kDefaultCdmIdentifier))
release_msg = GetUsageInfoResponse(config_.license_server(),
config_.client_auth(), usage_info[i]);
EXPECT_EQ(NO_ERROR,
decryptor_.ReleaseUsageInfo(release_msg, kDefaultCdmIdentifier))
<< i << "/" << usage_info.size() << " (err " << (error_count++) << ")"
<< release_msg;
}
ASSERT_LE(error_count, 100); // Give up after 100 failures.
status = decryptor_.GetUsageInfo("", kDefaultCdmIdentifier, &usage_info);
switch (status) {
case KEY_MESSAGE: EXPECT_FALSE(usage_info.empty()); break;
case NO_ERROR: EXPECT_TRUE(usage_info.empty()); break;
case KEY_MESSAGE:
EXPECT_FALSE(usage_info.empty());
break;
case NO_ERROR:
EXPECT_TRUE(usage_info.empty());
break;
default:
FAIL() << "GetUsageInfo failed with error " << static_cast<int>(status);
break;
@@ -1048,8 +1040,8 @@ TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnTimerEvent) {
// Leave session open to run the CDM timer
CdmSessionId streaming_session_id;
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&streaming_session_id);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &streaming_session_id);
// override default settings unless configured through the command line
std::string key_id;
@@ -1059,8 +1051,8 @@ TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnTimerEvent) {
uint32_t initial_open_sessions =
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline);
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
@@ -1070,8 +1062,8 @@ TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnTimerEvent) {
session_id_.clear();
key_set_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_);
@@ -1112,8 +1104,8 @@ TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnOpenSession) {
uint32_t initial_open_sessions =
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline);
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
@@ -1123,16 +1115,16 @@ TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnOpenSession) {
session_id_.clear();
key_set_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
decryptor_.CloseSession(session_id_);
session_id_.clear();
GenerateKeyRelease(key_set_id);
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
EXPECT_GT(
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS),
@@ -1150,8 +1142,8 @@ TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnOpenSession) {
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS),
initial_open_sessions);
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
EXPECT_GT(
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS),
@@ -1194,8 +1186,8 @@ TEST_F(WvCdmExtendedDurationTest, DISABLED_AutomatedOfflineSessionReleaseTest) {
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, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline);
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
@@ -1208,8 +1200,8 @@ TEST_F(WvCdmExtendedDurationTest, DISABLED_AutomatedOfflineSessionReleaseTest) {
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, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
EXPECT_EQ(wvcdm::KEY_ADDED, decryptor_.RestoreKey(session_id_, *iter));
decryptor_.CloseSession(session_id_);
}
@@ -1251,10 +1243,11 @@ TEST_P(WvCdmStreamingNoPstTest, UsageTest) {
Unprovision();
Provision();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(config_.key_id(), kLicenseTypeStreaming);
VerifyKeyRequestResponse(config_.license_server(), config_.client_auth(),
false);
ValidateResponse(video_widevine::STREAMING, false);
@@ -1326,10 +1319,11 @@ TEST_P(WvCdmStreamingPstTest, UsageTest) {
Unprovision();
Provision();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(kStreamingClip8PstInitData, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
VerifyKeyRequestResponse(config_.license_server(), config_.client_auth(),
false);
ValidateResponse(video_widevine::STREAMING, true);
@@ -1392,10 +1386,11 @@ TEST_P(WvCdmStreamingUsageReportTest, UsageTest) {
Unprovision();
Provision();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(kStreamingClip8PstInitData, kLicenseTypeStreaming);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
VerifyKeyRequestResponse(config_.license_server(), config_.client_auth(),
false);
ValidateResponse(video_widevine::STREAMING, true);
@@ -1450,8 +1445,8 @@ TEST_P(WvCdmStreamingUsageReportTest, UsageTest) {
// Create usage report and validate
CdmUsageInfo usage_info;
CdmUsageInfoReleaseMessage release_msg;
CdmResponseType status = decryptor_.GetUsageInfo(
"", kDefaultCdmIdentifier, &usage_info);
CdmResponseType status =
decryptor_.GetUsageInfo("", kDefaultCdmIdentifier, &usage_info);
EXPECT_EQ(usage_info.empty() ? NO_ERROR : KEY_MESSAGE, status);
int error_count = 0;
while (usage_info.size() > 0) {
@@ -1461,8 +1456,8 @@ TEST_P(WvCdmStreamingUsageReportTest, UsageTest) {
expected_seconds_since_license_received,
expected_seconds_since_initial_playback,
expected_seconds_since_last_playback);
release_msg =
GetUsageInfoResponse(g_license_server, g_client_auth, usage_info[i]);
release_msg = GetUsageInfoResponse(config_.license_server(),
config_.client_auth(), usage_info[i]);
EXPECT_EQ(NO_ERROR,
decryptor_.ReleaseUsageInfo(release_msg, kDefaultCdmIdentifier))
<< i << "/" << usage_info.size() << " (err " << (error_count++) << ")"
@@ -1500,10 +1495,11 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) {
Unprovision();
Provision();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(kOfflineClip2PstInitData, kLicenseTypeOffline);
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
VerifyKeyRequestResponse(config_.license_server(), config_.client_auth(),
false);
ValidateResponse(video_widevine::OFFLINE, true);
@@ -1524,8 +1520,8 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) {
for (size_t i = 0; i < GetParam(); ++i) {
session_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
// Query and validate usage information
@@ -1568,8 +1564,8 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) {
}
session_id_.clear();
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
EXPECT_EQ(KEY_ADDED, decryptor_.RestoreKey(session_id_, key_set_id));
// Query and validate usage information
@@ -1593,7 +1589,8 @@ TEST_P(WvCdmOfflineUsageReportTest, UsageTest) {
expected_seconds_since_initial_playback,
expected_seconds_since_last_playback);
key_set_id_ = key_set_id;
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
VerifyKeyRequestResponse(config_.license_server(), config_.client_auth(),
false);
}
INSTANTIATE_TEST_CASE_P(Cdm, WvCdmOfflineUsageReportTest,
@@ -1617,8 +1614,8 @@ TEST_F(WvCdmExtendedDurationTest, MaxUsageEntryOfflineRecoveryTest) {
// not encounter an error.
CdmResponseType response = NO_ERROR;
for (size_t i = 0; i < 2000; ++i) {
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline, &response);
if (response != KEY_MESSAGE) {
decryptor_.CloseSession(session_id_);
@@ -1638,8 +1635,8 @@ TEST_F(WvCdmExtendedDurationTest, MaxUsageEntryOfflineRecoveryTest) {
if (response != KEY_ADDED && response != KEY_MESSAGE) {
Provision();
for (size_t i = 0; i < 10; ++i) {
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
GenerateKeyRequest(key_id, kLicenseTypeOffline);
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
decryptor_.CloseSession(session_id_);
@@ -1648,112 +1645,3 @@ TEST_F(WvCdmExtendedDurationTest, MaxUsageEntryOfflineRecoveryTest) {
}
} // namespace wvcdm
void show_menu(char* prog_name) {
std::cout << std::endl;
std::cout << "usage: " << prog_name << " [options]" << std::endl << std::endl;
std::cout << " enclose multiple arguments in '' when using adb shell"
<< std::endl;
std::cout << " e.g. adb shell '" << prog_name << " --server=\"url\"'"
<< std::endl;
std::cout << " or adb shell '" << prog_name << " -u\"url\"'" << std::endl
<< std::endl;
std::cout << std::setw(37) << std::left
<< " -i/--license_server_id=<gp/cp/st>";
std::cout << "specifies which default server settings to use: " << std::endl;
std::cout << std::setw(37) << std::left << " ";
std::cout << "gp for GooglePlay server" << std::endl;
std::cout << std::setw(37) << std::left << " ";
std::cout << "cp for Content Protection UAT server" << std::endl;
std::cout << std::setw(37) << std::left << " ";
std::cout << "st for Content Protection Staging server" << std::endl
<< std::endl;
std::cout << std::setw(37) << std::left << " -k/--keyid=<key_id>";
std::cout << "configure the key id or pssh, in hex format" << std::endl
<< std::endl;
std::cout << std::setw(37) << std::left << " -u/--server=<server_url>";
std::cout
<< "configure the license server url, please include http[s] in the url"
<< std::endl << std::endl;
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
bool show_usage = false;
static const struct option long_options[] = {
{"keyid", required_argument, NULL, 'k'},
{"license_server_id", required_argument, NULL, 'i'},
{"license_server_url", required_argument, NULL, 'u'},
{NULL, 0, NULL, '\0'}};
int option_index = 0;
int opt = 0;
while ((opt = getopt_long(argc, argv, "i:k:u:", long_options,
&option_index)) != -1) {
switch (opt) {
case 'i': {
std::string license_id(optarg);
if (!license_id.compare("gp")) {
g_license_server_id = wvcdm::kGooglePlayServer;
} else if (!license_id.compare("cp")) {
g_license_server_id = wvcdm::kContentProtectionUatServer;
} else if (!license_id.compare("st")) {
g_license_server_id = wvcdm::kContentProtectionStagingServer;
} else {
std::cout << "Invalid license server id" << optarg << std::endl;
show_usage = true;
}
break;
}
case 'k': {
g_key_id.clear();
g_key_id.assign(optarg);
break;
}
case 'u': {
g_license_server.clear();
g_license_server.assign(optarg);
break;
}
case '?': {
show_usage = true;
break;
}
}
}
if (show_usage) {
show_menu(argv[0]);
return 0;
}
g_config = new wvcdm::ConfigTestEnv(g_license_server_id);
g_client_auth.assign(g_config->client_auth());
g_key_system.assign(g_config->key_system());
// The following variables are configurable through command line
// options. If the command line arguments are absent, use the settings
// in kLicenseServers[] pointed to by g_config.
if (g_key_id.empty()) {
g_key_id.assign(g_config->key_id());
}
if (g_license_server.empty()) {
g_license_server.assign(g_config->license_server());
}
// Displays server url, port and key Id being used
std::cout << std::endl;
std::cout << "Server: " << g_license_server << std::endl;
std::cout << "KeyID: " << g_key_id << std::endl << std::endl;
g_key_id = wvcdm::a2bs_hex(g_key_id);
g_config->set_license_server(g_license_server);
int status = RUN_ALL_TESTS();
delete g_config;
return status;
}

View File

@@ -22,12 +22,12 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "OEMCryptoCENC.h"
#include "config_test_env.h"
#include "license_protocol.pb.h"
#include "license_request.h"
#include "log.h"
#include "oemcrypto_adapter.h"
#include "OEMCryptoCENC.h"
#include "string_conversions.h"
#include "test_base.h"
#include "test_printers.h"
@@ -37,13 +37,13 @@
#include "wv_cdm_types.h"
#include "wv_content_decryption_module.h"
using ::testing::_;
using ::testing::Each;
using ::testing::Invoke;
using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::Pair;
using ::testing::StrictMock;
using ::testing::_;
namespace {
@@ -56,17 +56,6 @@ const int kHttpOk = 200;
// const int kHttpInternalServerError = 500;
const std::string kEmptyServiceCertificate;
// 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::ConfigTestEnv* g_config = NULL;
wvcdm::KeyId g_key_id;
wvcdm::CdmKeySystem g_key_system;
std::string g_license_server;
wvcdm::ServerConfigurationId g_license_server_id =
wvcdm::kContentProtectionUatServer;
std::string g_service_certificate;
wvcdm::KeyId kSrmHdKeyId1 = wvcdm::a2bs_hex("30303030303030303030303030303032");
wvcdm::KeyId kSrmHdKeyId2 = wvcdm::a2bs_hex("30303030303030303030303030303033");
wvcdm::KeyId kSrmHdKeyId3 = wvcdm::a2bs_hex("30303030303030303030303030303037");
@@ -410,8 +399,8 @@ class WvCdmFeatureTest : public WvCdmTestBase {
// To run this test set options,
// * use_keybox 0
TEST_F(WvCdmFeatureTest, OEMCertificateProvisioning) {
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key;
@@ -422,7 +411,7 @@ TEST_F(WvCdmFeatureTest, OEMCertificateProvisioning) {
kEmptyServiceCertificate,
&key_msg_,
&provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server());
EXPECT_EQ(provisioning_server_url, config_.provisioning_server());
ClientIdentification_TokenType token_type;
EXPECT_TRUE(ExtractTokenType(key_msg_, &token_type));
@@ -434,7 +423,7 @@ TEST_F(WvCdmFeatureTest, OEMCertificateProvisioning) {
"?key=AIzaSyB-5OLKTx2iU5mko18DfdwK5611JIjbUhE";
std::string response = GetCertRequestResponse(provisioning_server_url);
// GetCertRequestResponse(g_config->provisioning_server_url());
// GetCertRequestResponse(config_.provisioning_server_url());
EXPECT_NE(0, static_cast<int>(response.size()));
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.HandleProvisioningResponse(
@@ -447,8 +436,8 @@ TEST_F(WvCdmFeatureTest, OEMCertificateProvisioning) {
// To run this test set options,
// * use_keybox 1
TEST_F(WvCdmFeatureTest, KeyboxProvisioning) {
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
NULL, &session_id_);
std::string provisioning_server_url;
CdmCertificateType cert_type = kCertificateWidevine;
std::string cert_authority, cert, wrapped_key;
@@ -459,7 +448,7 @@ TEST_F(WvCdmFeatureTest, KeyboxProvisioning) {
kEmptyServiceCertificate,
&key_msg_,
&provisioning_server_url));
EXPECT_EQ(provisioning_server_url, g_config->provisioning_server());
EXPECT_EQ(provisioning_server_url, config_.provisioning_server());
ClientIdentification_TokenType token_type;
EXPECT_TRUE(ExtractTokenType(key_msg_, &token_type));
@@ -504,8 +493,8 @@ TEST_P(WvCdmSrmTest, Srm) {
StrictMock<TestWvCdmEventListener> listener;
TestKeyVerifier verify_keys_callback(config->expected_key_ids);
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, &listener,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
&listener, &session_id_);
EXPECT_CALL(listener,
OnSessionKeysChange(
@@ -524,7 +513,7 @@ TEST_P(WvCdmSrmTest, Srm) {
GenerateKeyRequest(init_data, kLicenseTypeStreaming);
VerifyKeyRequestResponse(
ConfigTestEnv::GetLicenseServerUrl(kContentProtectionStagingServer),
g_client_auth);
config_.client_auth());
EXPECT_EQ(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault,
@@ -561,8 +550,8 @@ TEST_P(WvCdmSrmNotSupportedTest, Srm) {
StrictMock<TestWvCdmEventListener> listener;
TestKeyVerifier verify_keys_callback(config->expected_key_ids);
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, &listener,
&session_id_);
decryptor_.OpenSession(config_.key_system(), NULL, kDefaultCdmIdentifier,
&listener, &session_id_);
EXPECT_CALL(listener,
OnSessionKeysChange(
@@ -581,7 +570,7 @@ TEST_P(WvCdmSrmNotSupportedTest, Srm) {
GenerateKeyRequest(init_data, kLicenseTypeStreaming);
VerifyKeyRequestResponse(
ConfigTestEnv::GetLicenseServerUrl(kContentProtectionStagingServer),
g_client_auth);
config_.client_auth());
EXPECT_NE(wvcdm::NO_ERROR,
decryptor_.QueryStatus(kLevelDefault,
@@ -596,134 +585,3 @@ INSTANTIATE_TEST_CASE_P(
&kSrmNotSupportedTestConfiguration[N_ELEM(
kSrmNotSupportedTestConfiguration)]));
} // namespace wvcdm
void show_menu(char* prog_name) {
std::cout << std::endl;
std::cout << "usage: " << prog_name << " [options]" << std::endl << std::endl;
std::cout << " enclose multiple arguments in '' when using adb shell"
<< std::endl;
std::cout << " e.g. adb shell '" << prog_name << " --server=\"url\"'"
<< std::endl;
std::cout << " or adb shell '" << prog_name << " -u\"url\"'" << std::endl
<< std::endl;
std::cout << " -i/--license_server_id=<gp/cp/st>" << std::endl;
std::cout << " specifies which default server settings to use: "
<< std::endl;
std::cout << " gp for GooglePlay server" << std::endl;
std::cout << " cp for Content Protection UAT server" << std::endl;
std::cout << " st for Content Protection Staging server" << std::endl
<< std::endl;
std::cout << " -k/--keyid=<key_id>" << std::endl;
std::cout << " configure the key id or pssh, in hex format" << std::endl
<< std::endl;
std::cout << " -s/--cert=<service_certificate>" << std::endl;
std::cout << " configure the signed service certificate" << std::endl;
std::cout << " Specify the SignedDeviceCertificate (from "
<< "device_certificate.proto) " << std::endl;
std::cout << " in hex format." << std::endl;
std::cout << " Due to the length of the argument use, " << std::endl;
std::cout << " echo \"/system/bin/request_license_test -s \\\""
<< "0ABF02...A29914\\\"\" \\" << std::endl;
std::cout << " > run_request_license_test.sh" << std::endl;
std::cout << " chmod +x run_request_license_test.sh" << std::endl;
std::cout << " adb push run_request_license_test.sh /system/bin"
<< std::endl;
std::cout << " adb shell sh /system/bin/run_request_license_test.sh"
<< std::endl
<< std::endl;
std::cout << " -u/--server=<server_url>" << std::endl;
std::cout << " configure the license server url, please include http[s]"
<< " in the url" << std::endl
<< std::endl;
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
bool show_usage = false;
static const struct option long_options[] = {
{"keyid", required_argument, NULL, 'k'},
{"license_server_id", required_argument, NULL, 'i'},
{"service_certificate", required_argument, NULL, 's'},
{"license_server_url", required_argument, NULL, 'u'},
{NULL, 0, NULL, '\0'}};
int option_index = 0;
int opt = 0;
while ((opt = getopt_long(argc, argv, "i:k:s:u:", long_options,
&option_index)) != -1) {
switch (opt) {
case 'i': {
std::string license_id(optarg);
if (!license_id.compare("gp")) {
g_license_server_id = wvcdm::kGooglePlayServer;
} else if (!license_id.compare("cp")) {
g_license_server_id = wvcdm::kContentProtectionUatServer;
} else if (!license_id.compare("st")) {
g_license_server_id = wvcdm::kContentProtectionStagingServer;
} else {
std::cout << "Invalid license server id" << optarg << std::endl;
show_usage = true;
}
break;
}
case 'k': {
g_key_id.clear();
g_key_id.assign(optarg);
break;
}
case 's': {
g_service_certificate.clear();
g_service_certificate.assign(optarg);
break;
}
case 'u': {
g_license_server.clear();
g_license_server.assign(optarg);
break;
}
case '?': {
show_usage = true;
break;
}
}
}
if (show_usage) {
show_menu(argv[0]);
return 0;
}
g_config = new wvcdm::ConfigTestEnv(g_license_server_id);
g_client_auth.assign(g_config->client_auth());
g_key_system.assign(g_config->key_system());
// The following variables are configurable through command line
// options. If the command line arguments are absent, use the settings
// in kLicenseServers[] pointed to by g_config.
if (g_key_id.empty()) {
g_key_id.assign(g_config->key_id());
}
if (g_service_certificate.empty()) {
g_service_certificate.assign(g_config->license_service_certificate());
}
if (g_license_server.empty()) {
g_license_server.assign(g_config->license_server());
}
// Displays server url, port and key Id being used
std::cout << std::endl;
std::cout << "Server: " << g_license_server << std::endl;
std::cout << "KeyID: " << g_key_id << std::endl << std::endl;
g_key_id = wvcdm::a2bs_hex(g_key_id);
g_config->set_license_server(g_license_server);
int status = RUN_ALL_TESTS();
delete g_config;
return status;
}

View File

@@ -0,0 +1,67 @@
# -------------------------------------------------------------------
# Makes a unit or end to end test.
# test_name must be passed in as the base filename(without the .cpp).
#
$(call assert-not-null,test_name)
include $(CLEAR_VARS)
LOCAL_MODULE := $(test_name)
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := \
$(test_main) \
$(test_src_dir)/$(test_name).cpp \
../../oemcrypto/test//oec_device_features.cpp \
../core/test/config_test_env.cpp \
../core/test/http_socket.cpp \
../core/test/license_request.cpp \
../core/test/test_base.cpp \
../core/test/test_printers.cpp \
../core/test/url_request.cpp
LOCAL_C_INCLUDES := \
vendor/widevine/libwvdrmengine/android/cdm/test \
vendor/widevine/libwvdrmengine/cdm/core/include \
vendor/widevine/libwvdrmengine/cdm/core/test \
vendor/widevine/libwvdrmengine/cdm/include \
vendor/widevine/libwvdrmengine/cdm/metrics/include \
vendor/widevine/libwvdrmengine/cdm/util/include \
vendor/widevine/libwvdrmengine/oemcrypto/include \
vendor/widevine/libwvdrmengine/oemcrypto/test \
LOCAL_C_INCLUDES += external/protobuf/src
LOCAL_STATIC_LIBRARIES := \
libcdm \
libcdm_protos \
libcdm_utils \
libcrypto_static \
libjsmn \
libgmock \
libgtest \
libwvlevel3 \
LOCAL_SHARED_LIBRARIES := \
libcutils \
libdl \
liblog \
libmedia_omx \
libprotobuf-cpp-lite \
libssl \
libstagefright_foundation \
libutils \
LOCAL_CFLAGS += -DUNIT_TEST
LOCAL_MODULE_OWNER := widevine
LOCAL_PROPRIETARY_MODULE := true
# When built, explicitly put it in the DATA/bin directory.
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/bin
ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
LOCAL_MODULE_TARGET_ARCH := arm x86 mips
endif
include $(BUILD_EXECUTABLE)

File diff suppressed because it is too large Load Diff