Merges to android Pi release (part 5)
These are a set of CLs merged from the wv cdm repo to the android repo. * Change build options for make protobuf host tools Author: Gene Morgan <gmorgan@google.com> [ Merge of http://go/wvgerrit/30381 ] Also revert local change to protobuf/extension_set.cc This builds after adding -Wno-return-type and -Wno-unused flags. * OEMCrypto v13 stub Author: Rintaro Kuroiwa <rkuroiwa@google.com> [ Merge of http://go/wvgerrit/30004 ] * Remove merge conflict tags Author: Edwin Wong <edwinwong@google.com> [ Merge of http://go/wvgerrit/30120 ] Remove merge conflict tags for http://go/wvgerrit/29880 * Added Android Things ARM provisioning key to L3 Author: Srujan Gaddam <srujzs@google.com> [ Merge of http://go/wvgerrit/29701 ] BUG: 63443584 BUG: 71650075 Test: Not currently passing. Will be addressed in a subsequent commit in the chain. Change-Id: Ifd867b491dfda5d67d2e225695535b5af9e18260
This commit is contained in:
@@ -43,9 +43,6 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libwvhidl \
|
||||
libbinder \
|
||||
|
||||
LOCAL_HEADER_LIBRARIES := \
|
||||
libstagefright_foundation_headers
|
||||
|
||||
LOCAL_MODULE := android.hardware.drm@1.0-service.widevine
|
||||
LOCAL_INIT_RC := src_hidl/android.hardware.drm@1.0-service.widevine.rc
|
||||
LOCAL_REQUIRED_MODULES := move_widevine_data.sh
|
||||
@@ -66,21 +63,14 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libcdm_utils
|
||||
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := libcrypto
|
||||
LOCAL_STATIC_LIBRARIES := libcrypto_static
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
vendor/widevine/libwvdrmengine/cdm/core/include \
|
||||
vendor/widevine/libwvdrmengine/cdm/include \
|
||||
vendor/widevine/libwvdrmengine/oemcrypto/include \
|
||||
|
||||
LOCAL_HEADER_LIBRARIES := \
|
||||
libutils_headers \
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
liblog
|
||||
|
||||
SRC_DIR := cdm/src
|
||||
CORE_SRC_DIR := cdm/core/src
|
||||
LOCAL_SRC_FILES := \
|
||||
@@ -104,10 +94,8 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libcdm_protos
|
||||
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
|
||||
CORE_PROTO_SRC_FILES := $(call all-proto-files-under, cdm/core/src)
|
||||
LOCAL_SRC_FILES := $(CORE_PROTO_SRC_FILES) $(METRICS_PROTO_SRC_FILES)
|
||||
LOCAL_SRC_FILES := $(call all-proto-files-under, cdm/core/src)
|
||||
|
||||
generated_sources_dir := $(call local-generated-sources-dir)
|
||||
|
||||
@@ -170,7 +158,7 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm \
|
||||
libcdm_protos \
|
||||
libcdm_utils \
|
||||
libcrypto \
|
||||
libcrypto_static \
|
||||
libjsmn \
|
||||
libwvdrmcryptoplugin \
|
||||
libwvdrmdrmplugin \
|
||||
@@ -184,10 +172,6 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libstagefright_foundation \
|
||||
libutils \
|
||||
|
||||
LOCAL_HEADER_LIBRARIES := \
|
||||
libutils_headers \
|
||||
libstagefright_headers
|
||||
|
||||
LOCAL_MODULE := libwvdrmengine
|
||||
|
||||
LOCAL_MODULE_RELATIVE_PATH := mediadrm
|
||||
@@ -230,7 +214,7 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libcdm \
|
||||
libcdm_protos \
|
||||
libcdm_utils \
|
||||
libcrypto \
|
||||
libcrypto_static \
|
||||
libjsmn \
|
||||
libwvdrmcryptoplugin_hidl \
|
||||
libwvdrmdrmplugin_hidl \
|
||||
|
||||
@@ -104,7 +104,26 @@ class CdmEngine {
|
||||
const CdmSessionId& session_id, const CdmKeySetId& key_set_id,
|
||||
const InitializationData& init_data, const CdmLicenseType license_type,
|
||||
CdmAppParameterMap& app_parameters, CdmKeyRequest* key_request);
|
||||
// Accept license response and extract key info.
|
||||
// This API may
|
||||
// (a) accept license response, extract key info and load keys.
|
||||
// (b) accept a renewal response and update license policy information.
|
||||
// (c) accept a release response and release an offline license or secure
|
||||
// stop.
|
||||
// (d) accept a service certificate and cache that information for the
|
||||
// the lifetime of the session.
|
||||
//
|
||||
// |session_id| identifies the session that generated the request and can
|
||||
// process the response. Should be empty if a release response.
|
||||
// |key_data| is the license, renewal, release response or service
|
||||
// certificate response.
|
||||
// |key_set_id| should be non-null and specified if license release.
|
||||
// If offline license or streaming license associated with
|
||||
// a secure stop, |key_set_id| should be non-null and will
|
||||
// be filled in on return. Use the |key_set_id| with
|
||||
// RestoreKeys (to reload offline session) or
|
||||
// GenerateKeyRequest (to release offline session/secure stop).
|
||||
// |key_set_id| will be cleared if release or streaming
|
||||
// (not associated with a secure stop).
|
||||
virtual CdmResponseType AddKey(const CdmSessionId& session_id,
|
||||
const CdmKeyResponse& key_data,
|
||||
CdmKeySetId* key_set_id);
|
||||
|
||||
@@ -87,8 +87,7 @@ class CdmSession {
|
||||
// ReleaseKey() - Accept response and release key.
|
||||
virtual CdmResponseType ReleaseKey(const CdmKeyResponse& key_response);
|
||||
|
||||
virtual CdmResponseType DeleteUsageEntry(
|
||||
const DeviceFiles::CdmUsageData& usage_data);
|
||||
virtual CdmResponseType DeleteUsageEntry(uint32_t usage_entry_number);
|
||||
|
||||
virtual bool IsKeyLoaded(const KeyId& key_id);
|
||||
virtual int64_t GetDurationRemaining();
|
||||
@@ -122,6 +121,10 @@ class CdmSession {
|
||||
virtual bool is_offline() { return is_offline_; }
|
||||
virtual bool is_temporary() { return is_temporary_; }
|
||||
virtual bool license_received() { return license_received_; }
|
||||
virtual bool has_provider_session_token() {
|
||||
return (license_parser_.get() != NULL &&
|
||||
license_parser_->provider_session_token().size() > 0);
|
||||
}
|
||||
|
||||
virtual CdmUsageSupportType get_usage_support_type()
|
||||
{ return usage_support_type_; }
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
namespace wvcdm {
|
||||
|
||||
class CryptoKey;
|
||||
class UsageTableHeader;
|
||||
|
||||
typedef std::map<CryptoKeyId, CryptoKey*> CryptoKeyMap;
|
||||
|
||||
class CryptoSession {
|
||||
@@ -145,6 +147,9 @@ class CryptoSession {
|
||||
const std::string& signature);
|
||||
|
||||
// Usage table header and usage entry related methods
|
||||
virtual UsageTableHeader* GetUsageTableHeader() {
|
||||
return usage_table_header_;
|
||||
}
|
||||
virtual CdmResponseType GetUsageSupportType(CdmUsageSupportType* type);
|
||||
virtual CdmResponseType CreateUsageTableHeader(
|
||||
CdmUsageTableHeader* usage_table_header);
|
||||
@@ -230,7 +235,11 @@ class CryptoSession {
|
||||
|
||||
KeyId cached_key_id_;
|
||||
|
||||
bool is_usage_support_type_valid_;
|
||||
CdmUsageSupportType usage_support_type_;
|
||||
UsageTableHeader* usage_table_header_;
|
||||
static UsageTableHeader* usage_table_header_l1_;
|
||||
static UsageTableHeader* usage_table_header_l3_;
|
||||
|
||||
uint64_t request_id_base_;
|
||||
static uint64_t request_id_index_;
|
||||
|
||||
@@ -21,6 +21,7 @@ class Clock;
|
||||
class CryptoSession;
|
||||
class PolicyEngine;
|
||||
class ServiceCertificate;
|
||||
class CdmSession;
|
||||
|
||||
class CdmLicense {
|
||||
public:
|
||||
@@ -38,7 +39,8 @@ class CdmLicense {
|
||||
std::string* server_url);
|
||||
virtual CdmResponseType PrepareKeyUpdateRequest(
|
||||
bool is_renewal, const CdmAppParameterMap& app_parameters,
|
||||
CdmKeyMessage* signed_request, std::string* server_url);
|
||||
CdmSession* cdm_session, CdmKeyMessage* signed_request,
|
||||
std::string* server_url);
|
||||
virtual CdmResponseType HandleKeyResponse(
|
||||
const CdmKeyResponse& license_response);
|
||||
virtual CdmResponseType HandleKeyUpdateResponse(
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "device_files.h"
|
||||
#include "file_store.h"
|
||||
#include "lock.h"
|
||||
#include "metrics_group.h"
|
||||
#include "scoped_ptr.h"
|
||||
@@ -15,28 +16,40 @@
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
class FileSystem;
|
||||
class CryptoSession;
|
||||
|
||||
// The UsageTableHeader class is a singleton that CDM sessions will share.
|
||||
// A separate object will be created for each security level.
|
||||
// The class synchronizes access to usage table header and associated
|
||||
// data-structures and controls when they are read in or written out to
|
||||
// non-secure persistent storage.
|
||||
// Offline licenses/secure stops may be securely tracked using usage
|
||||
// tables (OEMCrypto v9-12) or usage table headers+usage entries
|
||||
// (OEMCrypto v13+). This class assists with the latter, synchronizing
|
||||
// access to usage table header and associated data-structures and controlling
|
||||
// when they are read in or written out to non-secure persistent storage.
|
||||
//
|
||||
// Each OEMCrypto (for each security level) will maintain its own usage table
|
||||
// header. Each license will have an associated usage entry that is also
|
||||
// stored in persistent memory and is noted in the usage table header.
|
||||
// Usage entry information will be verified when licenses are loaded.
|
||||
//
|
||||
// OEMCrypto for each security level have their own usage table
|
||||
// headers. They are loaded on initialization and written out periodically.
|
||||
// The lifecycle of this class is tied to when OEMCrypto is
|
||||
// initialized/terminated.
|
||||
//
|
||||
// Sessions and licenses are however handled by CdmSession and so most
|
||||
// calls to maniplate the usage table header related to usage entries
|
||||
// are by CdmSession.
|
||||
//
|
||||
// Upgrades from a fixed size usage table (supported by previous
|
||||
// versions of the OEMCrypto API v9-12) are handled by this class.
|
||||
// |usage_entry| and |usage_entry_number| need to be saved in the license
|
||||
// |usage_entry| and |usage_entry_number|s need to be saved in the license
|
||||
// and usage info records by the caller.
|
||||
class UsageTableHeader {
|
||||
public:
|
||||
// This methods instantiates or retrieves a usage table header singleton of
|
||||
// appropriate security level as specified by the |crypto_session|
|
||||
// object.
|
||||
UsageTableHeader();
|
||||
virtual ~UsageTableHeader() {}
|
||||
|
||||
// |crypto_session| is used to create or load a usage master table and
|
||||
// not cached beyound this call.
|
||||
static UsageTableHeader* GetInstance(FileSystem* file_system,
|
||||
CryptoSession* crypto_session_);
|
||||
virtual ~UsageTableHeader() {}
|
||||
bool Init(CdmSecurityLevel security_level, CryptoSession* crypto_session);
|
||||
|
||||
// |persistent_license| false indicates usage info record
|
||||
CdmResponseType AddEntry(CryptoSession* crypto_session,
|
||||
@@ -53,56 +66,67 @@ class UsageTableHeader {
|
||||
// The licenses or usage info records specified by |usage_entry_number|
|
||||
// should not be in use by any open CryptoSession objects when calls
|
||||
// to DeleteEntry and MoveEntry are made.
|
||||
CdmResponseType DeleteEntry(uint32_t usage_entry_number);
|
||||
CdmResponseType MoveEntry(uint32_t from_usage_entry_number,
|
||||
const CdmUsageEntry& from_usage_entry,
|
||||
uint32_t to_usage_entry_number);
|
||||
CdmResponseType DeleteEntry(uint32_t usage_entry_number, DeviceFiles* handle,
|
||||
metrics::MetricsGroup* metrics);
|
||||
|
||||
private:
|
||||
UsageTableHeader(FileSystem* file_system, CryptoSession* crypto_session,
|
||||
CdmSecurityLevel security_level);
|
||||
CdmResponseType MoveEntry(uint32_t from /* usage entry number */,
|
||||
const CdmUsageEntry& from_usage_entry,
|
||||
uint32_t to /* usage entry number */,
|
||||
DeviceFiles* handle,
|
||||
metrics::MetricsGroup* metrics);
|
||||
|
||||
CdmResponseType GetEntry(uint32_t usage_entry_number,
|
||||
CdmResponseType GetEntry(uint32_t usage_entry_number, DeviceFiles* handle,
|
||||
CdmUsageEntry* usage_entry);
|
||||
CdmResponseType StoreEntry(uint32_t usage_entry_number,
|
||||
CdmResponseType StoreEntry(uint32_t usage_entry_number, DeviceFiles* handle,
|
||||
const CdmUsageEntry& usage_entry);
|
||||
|
||||
bool DeleteLastEntry();
|
||||
CdmResponseType Shrink(metrics::MetricsGroup* metrics,
|
||||
uint32_t number_of_usage_entries_to_delete);
|
||||
|
||||
CdmResponseType UpgradeFromUsageTable();
|
||||
|
||||
// Indicates whether one of more license/usage records failed to be upgraded.
|
||||
bool UpgradeLicensesFromUsageTable();
|
||||
bool UpgradeUsageInfoFromUsageTable();
|
||||
CdmResponseType UpgradeFromUsageTable(DeviceFiles* handle,
|
||||
metrics::MetricsGroup* metrics);
|
||||
bool UpgradeLicensesFromUsageTable(DeviceFiles* handle,
|
||||
metrics::MetricsGroup* metrics);
|
||||
bool UpgradeUsageInfoFromUsageTable(DeviceFiles* handle,
|
||||
metrics::MetricsGroup* metrics);
|
||||
|
||||
virtual bool is_inited() { return is_inited_; }
|
||||
|
||||
SecurityLevel GetSecurityLevel() {
|
||||
return security_level_ == kSecurityLevelL3 ? kLevel3 : kLevelDefault;
|
||||
}
|
||||
|
||||
static UsageTableHeader* usage_table_header_l1_;
|
||||
static UsageTableHeader* usage_table_header_l3_;
|
||||
|
||||
// This handle and file system is only to be used when accessing
|
||||
// usage_table_header. Usage entries should use the file system provided
|
||||
// by CdmSession.
|
||||
scoped_ptr<DeviceFiles> file_handle_;
|
||||
scoped_ptr<FileSystem> file_system_;
|
||||
CdmSecurityLevel security_level_;
|
||||
SecurityLevel requested_security_level_;
|
||||
|
||||
CdmUsageTableHeader usage_table_header_;
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_;
|
||||
|
||||
metrics::MetricsGroup metrics_;
|
||||
metrics::TimerMetric life_span_;
|
||||
|
||||
// Lock to ensure that a single object is created for each security level
|
||||
// and data member to represent whether an object has been correctly
|
||||
// initialized.
|
||||
bool is_inited_;
|
||||
static Lock initialization_lock_;
|
||||
|
||||
// Synchonizes access to the Usage Table Header and bookkeeping
|
||||
// data-structures
|
||||
Lock usage_table_header_lock_;
|
||||
|
||||
// Test related declarations
|
||||
friend class UsageTableHeaderTest;
|
||||
|
||||
// These setters are for testing only. Takes ownership of the pointers.
|
||||
void SetDeviceFiles(DeviceFiles* device_files) {
|
||||
file_handle_.reset(device_files);
|
||||
}
|
||||
void SetCryptoSession(CryptoSession* crypto_session) {
|
||||
test_crypto_session_.reset(crypto_session);
|
||||
}
|
||||
|
||||
// Test related data members
|
||||
scoped_ptr<CryptoSession> test_crypto_session_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(UsageTableHeader);
|
||||
};
|
||||
|
||||
|
||||
@@ -64,6 +64,10 @@ static const std::string QUERY_KEY_MAX_NUMBER_OF_SESSIONS =
|
||||
"MaxNumberOfSessions";
|
||||
static const std::string QUERY_KEY_OEMCRYPTO_API_VERSION =
|
||||
"OemCryptoApiVersion";
|
||||
static const std::string QUERY_KEY_CURRENT_SRM_VERSION = "CurrentSRMVersion";
|
||||
static const std::string QUERY_KEY_SRM_UPDATE_SUPPORT = "SRMUpdateSupport";
|
||||
// whether OEM supports SRM update
|
||||
static const std::string QUERY_KEY_WVCDM_VERSION = "WidevineCdmVersion";
|
||||
|
||||
static const std::string QUERY_VALUE_TRUE = "True";
|
||||
static const std::string QUERY_VALUE_FALSE = "False";
|
||||
|
||||
@@ -407,13 +407,19 @@ enum CdmUsageSupportType {
|
||||
enum CdmUsageEntryStorageType {
|
||||
kStorageLicense,
|
||||
kStorageUsageInfo,
|
||||
kStorageUnknown,
|
||||
kStorageTypeUnknown,
|
||||
};
|
||||
|
||||
struct CdmUsageEntryInfo {
|
||||
CdmUsageEntryStorageType storage_type;
|
||||
CdmKeySetId key_set_id;
|
||||
std::string usage_info_file_name;
|
||||
bool operator==(const CdmUsageEntryInfo& other) const {
|
||||
return storage_type == other.storage_type &&
|
||||
key_set_id == other.key_set_id &&
|
||||
(storage_type != kStorageUsageInfo ||
|
||||
usage_info_file_name == other.usage_info_file_name);
|
||||
}
|
||||
};
|
||||
|
||||
class CdmKeyAllowedUsage {
|
||||
|
||||
@@ -409,7 +409,12 @@ CdmResponseType CdmEngine::AddKey(const CdmSessionId& session_id,
|
||||
|
||||
CdmResponseType sts = session->AddKey(key_data);
|
||||
if (key_set_id) {
|
||||
*key_set_id = session->key_set_id();
|
||||
if ((session->is_offline() ||
|
||||
session->has_provider_session_token()) && !license_type_release) {
|
||||
*key_set_id = session->key_set_id();
|
||||
} else {
|
||||
key_set_id->clear();
|
||||
}
|
||||
}
|
||||
|
||||
switch (sts) {
|
||||
@@ -681,6 +686,28 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
||||
std::ostringstream api_version_stream;
|
||||
api_version_stream << api_version;
|
||||
*query_response = api_version_stream.str();
|
||||
} else if (query_token == QUERY_KEY_CURRENT_SRM_VERSION) {
|
||||
uint16_t current_srm_version;
|
||||
if (!crypto_session.GetSrmVersion(¤t_srm_version)) {
|
||||
LOGW("CdmEngine::QueryStatus: GetCurrentSRMVersion failed");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
std::ostringstream current_srm_version_stream;
|
||||
current_srm_version_stream << current_srm_version;
|
||||
*query_response = current_srm_version_stream.str();
|
||||
} else if (query_token == QUERY_KEY_SRM_UPDATE_SUPPORT) {
|
||||
bool is_srm_update_supported = crypto_session.IsSrmUpdateSupported();
|
||||
*query_response =
|
||||
is_srm_update_supported ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE;
|
||||
} else if (query_token == QUERY_KEY_WVCDM_VERSION) {
|
||||
std::string cdm_version;
|
||||
if (!Properties::GetWVCdmVersion(&cdm_version)) {
|
||||
LOGW("CdmEngine::QueryStatus: GetWVCdmVersion failed");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
*query_response = cdm_version;
|
||||
} else {
|
||||
LOGW("CdmEngine::QueryStatus: Unknown status requested, token = %s",
|
||||
query_token.c_str());
|
||||
@@ -1261,42 +1288,47 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
|
||||
usage_session_.reset(new CdmSession(file_system_));
|
||||
usage_session_->Init(usage_property_set_.get());
|
||||
|
||||
if (usage_session_->get_usage_support_type() == kUsageEntrySupport) {
|
||||
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
||||
if (!handle.RetrieveUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&usage_data)) {
|
||||
status = RELEASE_ALL_USAGE_INFO_ERROR_4;
|
||||
} else {
|
||||
for (size_t k = 0; k < usage_data.size(); ++k) {
|
||||
CdmResponseType status2 =
|
||||
usage_session_->DeleteUsageEntry(usage_data[k]);
|
||||
if (status == NO_ERROR && status2 != NO_ERROR)
|
||||
status = status2;
|
||||
switch (usage_session_->get_usage_support_type()) {
|
||||
case kUsageEntrySupport: {
|
||||
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
||||
if (!handle.RetrieveUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), &usage_data)) {
|
||||
status = RELEASE_ALL_USAGE_INFO_ERROR_4;
|
||||
} else {
|
||||
for (size_t k = 0; k < usage_data.size(); ++k) {
|
||||
CdmResponseType status2 = usage_session_->DeleteUsageEntry(
|
||||
usage_data[k].usage_entry_number);
|
||||
if (status == NO_ERROR && status2 != NO_ERROR)
|
||||
status = status2;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
if (!handle.DeleteAllUsageInfoForApp(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&provider_session_tokens)) {
|
||||
status = RELEASE_ALL_USAGE_INFO_ERROR_5;
|
||||
}
|
||||
} else if (usage_session_->get_usage_support_type()
|
||||
== kUsageTableSupport) {
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
if (!handle.DeleteAllUsageInfoForApp(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&provider_session_tokens)) {
|
||||
LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete L%d secure"
|
||||
"stops", j);
|
||||
status = RELEASE_ALL_USAGE_INFO_ERROR_1;
|
||||
} else {
|
||||
CdmResponseType status2 = usage_session_->
|
||||
DeleteMultipleUsageInformation(provider_session_tokens);
|
||||
if (status2 != NO_ERROR) {
|
||||
status = status2;
|
||||
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
if (!handle.DeleteAllUsageInfoForApp(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&provider_session_tokens)) {
|
||||
status = RELEASE_ALL_USAGE_INFO_ERROR_5;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kUsageTableSupport: {
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
if (!handle.DeleteAllUsageInfoForApp(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
&provider_session_tokens)) {
|
||||
LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete %d secure"
|
||||
"stops", j);
|
||||
status = RELEASE_ALL_USAGE_INFO_ERROR_1;
|
||||
} else {
|
||||
CdmResponseType status2 = usage_session_->
|
||||
DeleteMultipleUsageInformation(provider_session_tokens);
|
||||
if (status2 != NO_ERROR) status = status2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
LOGE("CdmEngine::ReleaseAllUsageInfo: failed to initialize L%d device"
|
||||
@@ -1611,25 +1643,25 @@ void CdmEngine::OnTimerEvent() {
|
||||
for (CdmSessionList::iterator iter = sessions.begin();
|
||||
iter != sessions.end(); ++iter) {
|
||||
(*iter)->reset_usage_flags();
|
||||
if ((*iter)->get_usage_support_type() == kUsageEntrySupport)
|
||||
(*iter)->UpdateUsageEntryInformation();
|
||||
|
||||
if (!has_usage_been_updated) {
|
||||
// usage is updated for all sessions so this needs to be
|
||||
// called only once per update usage information period
|
||||
if ((*iter)->get_usage_support_type() == kUsageTableSupport) {
|
||||
CdmResponseType status;
|
||||
M_TIME(
|
||||
status = (*iter)->UpdateUsageTableInformation(),
|
||||
(*iter)->GetMetrics(),
|
||||
crypto_session_update_usage_information_,
|
||||
status);
|
||||
if (NO_ERROR != status) {
|
||||
LOGW("Update usage information failed: %d", status);
|
||||
} else {
|
||||
has_usage_been_updated = true;
|
||||
switch ((*iter)->get_usage_support_type()) {
|
||||
case kUsageEntrySupport:
|
||||
(*iter)->UpdateUsageEntryInformation();
|
||||
break;
|
||||
case kUsageTableSupport:
|
||||
if (!has_usage_been_updated) {
|
||||
// usage is updated for all sessions so this needs to be
|
||||
// called only once per update usage information period
|
||||
CdmResponseType status = (*iter)->UpdateUsageTableInformation();
|
||||
if (NO_ERROR != status) {
|
||||
LOGW("Update usage information failed: %d", status);
|
||||
} else {
|
||||
has_usage_been_updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,15 +45,6 @@ CdmSession::CdmSession(FileSystem* file_system) :
|
||||
usage_entry_number_(0),
|
||||
mock_license_parser_in_use_(false),
|
||||
mock_policy_engine_in_use_(false) {
|
||||
CdmResponseType sts =
|
||||
crypto_session_->GetUsageSupportType(&usage_support_type_);
|
||||
|
||||
if (sts != NO_ERROR) {
|
||||
LOGW("CdmSession::CdmSession: Failed to get usage support type");
|
||||
}
|
||||
if (usage_support_type_ == kUsageEntrySupport)
|
||||
usage_table_header_ = UsageTableHeader::GetInstance(file_system,
|
||||
crypto_session_.get());
|
||||
life_span_.Start();
|
||||
}
|
||||
|
||||
@@ -106,6 +97,13 @@ CdmResponseType CdmSession::Init(
|
||||
return SESSION_FILE_HANDLE_INIT_ERROR;
|
||||
}
|
||||
|
||||
if (crypto_session_->GetUsageSupportType(&usage_support_type_) == NO_ERROR) {
|
||||
if (usage_support_type_ == kUsageEntrySupport)
|
||||
usage_table_header_ = crypto_session_->GetUsageTableHeader();
|
||||
} else {
|
||||
usage_support_type_ = kNonSecureUsageSupport;
|
||||
}
|
||||
|
||||
// Device Provisioning state is not yet known.
|
||||
// If not using certificates, then Keybox is client token for license
|
||||
// requests.
|
||||
@@ -195,6 +193,9 @@ CdmResponseType CdmSession::Init(
|
||||
|
||||
CdmResponseType CdmSession::RestoreOfflineSession(
|
||||
const CdmKeySetId& key_set_id, const CdmLicenseType license_type) {
|
||||
if (!key_set_id_.empty()) {
|
||||
file_handle_->UnreserveLicenseId(key_set_id_);
|
||||
}
|
||||
key_set_id_ = key_set_id;
|
||||
|
||||
DeviceFiles::LicenseState license_state;
|
||||
@@ -430,7 +431,8 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
|
||||
!provider_session_token.empty()) {
|
||||
if (sts != KEY_ADDED) {
|
||||
CdmResponseType sts =
|
||||
usage_table_header_->DeleteEntry(usage_entry_number_);
|
||||
usage_table_header_->DeleteEntry(usage_entry_number_,
|
||||
file_handle_.get(), &metrics_);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGW("CdmSession::AddKey: Delete usage entry failed = %d", sts);
|
||||
}
|
||||
@@ -446,7 +448,7 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
|
||||
license_parser_->provider_session_token().size(),
|
||||
license_parser_->provider_session_token().c_str());
|
||||
|
||||
if (is_offline_ || !license_parser_->provider_session_token().empty()) {
|
||||
if (is_offline_ || has_provider_session_token()) {
|
||||
if (usage_support_type_ == kUsageEntrySupport)
|
||||
usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_);
|
||||
|
||||
@@ -556,8 +558,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
|
||||
}
|
||||
has_decrypted_since_last_report_ = true;
|
||||
if (!is_usage_update_needed_) {
|
||||
is_usage_update_needed_ =
|
||||
!license_parser_->provider_session_token().empty();
|
||||
is_usage_update_needed_ = has_provider_session_token();
|
||||
}
|
||||
} else {
|
||||
Clock clock;
|
||||
@@ -576,7 +577,7 @@ CdmResponseType CdmSession::Decrypt(const CdmDecryptionParameters& params) {
|
||||
CdmResponseType CdmSession::GenerateRenewalRequest(
|
||||
CdmKeyRequest* key_request) {
|
||||
CdmResponseType status = license_parser_->PrepareKeyUpdateRequest(
|
||||
true, app_parameters_, &key_request->message, &key_request->url);
|
||||
true, app_parameters_, NULL, &key_request->message, &key_request->url);
|
||||
|
||||
key_request->type = kKeyRequestTypeRenewal;
|
||||
|
||||
@@ -606,8 +607,8 @@ CdmResponseType CdmSession::GenerateReleaseRequest(
|
||||
CdmKeyRequest* key_request) {
|
||||
is_release_ = true;
|
||||
CdmResponseType status = license_parser_->PrepareKeyUpdateRequest(
|
||||
false, app_parameters_, &key_request->message,
|
||||
&key_request->url);
|
||||
false, app_parameters_, usage_table_header_ == NULL ? NULL : this,
|
||||
&key_request->message, &key_request->url);
|
||||
|
||||
key_request->type = kKeyRequestTypeRelease;
|
||||
|
||||
@@ -641,38 +642,53 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
|
||||
license_parser_->HandleKeyUpdateResponse(false, key_response);
|
||||
if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? RELEASE_KEY_ERROR : sts;
|
||||
|
||||
if (is_offline_ || !license_parser_->provider_session_token().empty()) {
|
||||
if (is_offline_ || has_provider_session_token()) {
|
||||
DeleteLicense();
|
||||
|
||||
// Deletion of usage entry cannot occur while in use by a crypto session.
|
||||
// So close and reopen after deletion.
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
crypto_session_->Close();
|
||||
|
||||
CdmResponseType sts = usage_table_header_->DeleteEntry(usage_entry_number_);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
|
||||
M_TIME(
|
||||
sts = crypto_session_->Open(requested_security_level_),
|
||||
&metrics_,
|
||||
crypto_session_open_,
|
||||
sts,
|
||||
requested_security_level_);
|
||||
sts = DeleteUsageEntry(usage_entry_number_);
|
||||
if (NO_ERROR != sts) return sts;
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::DeleteUsageEntry(
|
||||
const DeviceFiles::CdmUsageData& usage_data) {
|
||||
CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
|
||||
if (usage_support_type_ != kUsageEntrySupport) {
|
||||
LOGE("CdmSession::DeleteUsageEntry: Unexpected usage type supported: %d",
|
||||
usage_support_type_);
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_1;
|
||||
}
|
||||
|
||||
return usage_table_header_->DeleteEntry(usage_data.usage_entry_number);
|
||||
// The usage entry cannot be deleted if it has a crypto session handling
|
||||
// it, so close and reopen session.
|
||||
CdmResponseType sts;
|
||||
crypto_session_->Close();
|
||||
crypto_session_.reset(new CryptoSession(&metrics_));
|
||||
M_TIME(
|
||||
sts = crypto_session_->Open(requested_security_level_),
|
||||
&metrics_,
|
||||
crypto_session_open_,
|
||||
sts,
|
||||
requested_security_level_);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
|
||||
usage_table_header_ = NULL;
|
||||
if (crypto_session_->GetUsageSupportType(&usage_support_type_) == NO_ERROR) {
|
||||
if (usage_support_type_ == kUsageEntrySupport)
|
||||
usage_table_header_ = crypto_session_->GetUsageTableHeader();
|
||||
} else {
|
||||
usage_support_type_ = kNonSecureUsageSupport;
|
||||
}
|
||||
|
||||
if (usage_table_header_ == NULL) {
|
||||
LOGE("CdmSession::DeleteUsageEntry: Usage table header unavailable");
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_1;
|
||||
}
|
||||
|
||||
return usage_table_header_->DeleteEntry(usage_entry_number,
|
||||
file_handle_.get(),
|
||||
&metrics_);
|
||||
}
|
||||
|
||||
bool CdmSession::IsKeyLoaded(const KeyId& key_id) {
|
||||
@@ -775,7 +791,7 @@ CdmResponseType CdmSession::ReleaseCrypto() {
|
||||
}
|
||||
|
||||
bool CdmSession::DeleteLicense() {
|
||||
if (!is_offline_ && license_parser_->provider_session_token().empty())
|
||||
if (!is_offline_ && !has_provider_session_token())
|
||||
return false;
|
||||
|
||||
if (is_offline_) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "properties.h"
|
||||
#include "pst_report.h"
|
||||
#include "string_conversions.h"
|
||||
#include "usage_table_header.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace {
|
||||
@@ -41,6 +42,8 @@ Lock CryptoSession::crypto_lock_;
|
||||
bool CryptoSession::initialized_ = false;
|
||||
int CryptoSession::session_count_ = 0;
|
||||
uint64_t CryptoSession::request_id_index_ = 0;
|
||||
UsageTableHeader* CryptoSession::usage_table_header_l1_ = NULL;
|
||||
UsageTableHeader* CryptoSession::usage_table_header_l3_ = NULL;
|
||||
|
||||
CryptoSession::CryptoSession(metrics::MetricsGroup* metrics)
|
||||
: metrics_(metrics),
|
||||
@@ -48,7 +51,9 @@ CryptoSession::CryptoSession(metrics::MetricsGroup* metrics)
|
||||
update_usage_table_after_close_session_(false),
|
||||
is_destination_buffer_type_valid_(false),
|
||||
requested_security_level_(kLevelDefault),
|
||||
usage_support_type_(kUnknownUsageSupport),
|
||||
is_usage_support_type_valid_(false),
|
||||
usage_support_type_(kNonSecureUsageSupport),
|
||||
usage_table_header_(NULL),
|
||||
request_id_base_(0),
|
||||
cipher_mode_(kCipherModeCtr) {
|
||||
Init();
|
||||
@@ -121,6 +126,16 @@ void CryptoSession::Terminate() {
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
LOGE("OEMCrypto_Terminate failed: %d", sts);
|
||||
}
|
||||
|
||||
if (usage_table_header_l1_ != NULL) {
|
||||
delete usage_table_header_l1_;
|
||||
usage_table_header_l1_ = NULL;
|
||||
}
|
||||
if (usage_table_header_l3_ != NULL) {
|
||||
delete usage_table_header_l3_;
|
||||
usage_table_header_l3_ = NULL;
|
||||
}
|
||||
|
||||
initialized_ = false;
|
||||
}
|
||||
|
||||
@@ -217,8 +232,7 @@ bool CryptoSession::GetProvisioningToken(std::string* token) {
|
||||
}
|
||||
|
||||
CdmSecurityLevel CryptoSession::GetSecurityLevel() {
|
||||
LOGV("CryptoSession::GetSecurityLevel: Lock");
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
LOGV("CryptoSession::GetSecurityLevel");
|
||||
if (!initialized_) {
|
||||
return kSecurityLevelUninitialized;
|
||||
}
|
||||
@@ -430,7 +444,8 @@ uint8_t CryptoSession::GetSecurityPatchLevel() {
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
||||
LOGV("CryptoSession::Open: Lock");
|
||||
LOGV("CryptoSession::Open: Lock: requested_security_level: %d",
|
||||
requested_security_level);
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
if (!initialized_) return UNKNOWN_ERROR;
|
||||
if (open_) return NO_ERROR;
|
||||
@@ -470,8 +485,35 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
||||
random_sts,
|
||||
metrics::Pow2Bucket(sizeof(request_id_base_)));
|
||||
++request_id_index_;
|
||||
|
||||
CdmUsageSupportType usage_support_type;
|
||||
GetUsageSupportType(&usage_support_type);
|
||||
if (GetUsageSupportType(&usage_support_type) == NO_ERROR) {
|
||||
if (usage_support_type == kUsageEntrySupport) {
|
||||
CdmSecurityLevel security_level = GetSecurityLevel();
|
||||
if (security_level == kSecurityLevelL1 ||
|
||||
security_level == kSecurityLevelL3) {
|
||||
UsageTableHeader* header = security_level == kSecurityLevelL1 ?
|
||||
usage_table_header_l1_ : usage_table_header_l3_;
|
||||
if (header == NULL) {
|
||||
header = new UsageTableHeader();
|
||||
// Ignore errors since we do not know when a session is opened,
|
||||
// if it is intended to be used for offline/usage session related
|
||||
// or otherwise.
|
||||
if (!header->Init(security_level, this)) {
|
||||
delete header;
|
||||
usage_table_header_ = NULL;
|
||||
return NO_ERROR;
|
||||
}
|
||||
if (security_level == kSecurityLevelL1)
|
||||
usage_table_header_l1_ = header;
|
||||
else
|
||||
usage_table_header_l3_ = header;
|
||||
}
|
||||
usage_table_header_ = header;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -1108,6 +1150,11 @@ CdmResponseType CryptoSession::UpdateUsageInformation() {
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
if (!initialized_) return UNKNOWN_ERROR;
|
||||
|
||||
if (usage_table_header_ != NULL) {
|
||||
LOGV("UpdateUsageInformation: deprecated for OEMCrypto v13+");
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
OEMCryptoResult status;
|
||||
M_TIME(
|
||||
status = OEMCrypto_UpdateUsageTable(),
|
||||
@@ -1264,6 +1311,11 @@ CdmResponseType CryptoSession::ReleaseUsageInformation(
|
||||
LOGV("ReleaseUsageInformation: id=%ld", (uint32_t)oec_session_id_);
|
||||
{
|
||||
AutoLock auto_lock(crypto_lock_);
|
||||
if (usage_table_header_ != NULL) {
|
||||
LOGW("ReleaseUsageInformation: deprecated for OEMCrypto v13+");
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
const uint8_t* msg = reinterpret_cast<const uint8_t*>(message.data());
|
||||
const uint8_t* sig = reinterpret_cast<const uint8_t*>(signature.data());
|
||||
const uint8_t* pst = msg + GetOffset(message, provider_session_token);
|
||||
|
||||
@@ -858,6 +858,11 @@ bool DeviceFiles::ListUsageInfoFiles(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usage_info_file_names == NULL) {
|
||||
LOGW("DeviceFiles::ListUsageInfoFiles: usage_info_file_names not provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get list of filenames
|
||||
std::vector<std::string> filenames;
|
||||
if (!ListFiles(&filenames)) {
|
||||
@@ -982,7 +987,7 @@ bool DeviceFiles::StoreUsageTableInfo(
|
||||
const CdmUsageTableHeader& usage_table_header,
|
||||
const std::vector<CdmUsageEntryInfo>& usage_entry_info) {
|
||||
if (!initialized_) {
|
||||
LOGW("DeviceFiles::StoreUsageTableHeader: not initialized");
|
||||
LOGW("DeviceFiles::StoreUsageTableInfo: not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1009,7 +1014,7 @@ bool DeviceFiles::StoreUsageTableInfo(
|
||||
info->set_usage_info_file_name(
|
||||
usage_entry_info[i].usage_info_file_name);
|
||||
break;
|
||||
case kStorageUnknown:
|
||||
case kStorageTypeUnknown:
|
||||
default:
|
||||
info->set_storage(
|
||||
UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN);
|
||||
@@ -1081,7 +1086,7 @@ bool DeviceFiles::RetrieveUsageTableInfo(
|
||||
break;
|
||||
case UsageTableInfo_UsageEntryInfo_UsageEntryStorage_UNKNOWN:
|
||||
default:
|
||||
(*usage_entry_info)[i].storage_type = kStorageUnknown;
|
||||
(*usage_entry_info)[i].storage_type = kStorageTypeUnknown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "clock.h"
|
||||
#include "cdm_session.h"
|
||||
#include "crypto_key.h"
|
||||
#include "crypto_session.h"
|
||||
#include "device_files.h"
|
||||
@@ -274,7 +275,8 @@ CdmResponseType CdmLicense::PrepareKeyRequest(
|
||||
|
||||
CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
||||
bool is_renewal, const CdmAppParameterMap& app_parameters,
|
||||
CdmKeyMessage* signed_request, std::string* server_url) {
|
||||
CdmSession* cdm_session, CdmKeyMessage* signed_request,
|
||||
std::string* server_url) {
|
||||
if (!initialized_) {
|
||||
LOGE("CdmLicense::PrepareKeyUpdateRequest: not initialized");
|
||||
return LICENSE_PARSER_NOT_INITIALIZED_1;
|
||||
@@ -330,6 +332,12 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
||||
if (NO_ERROR != status) return status;
|
||||
}
|
||||
|
||||
// TODO(rfrias): Refactor to avoid needing to call CdmSession
|
||||
if (cdm_session) {
|
||||
CdmResponseType status = cdm_session->UpdateUsageEntryInformation();
|
||||
if (NO_ERROR != status) return status;
|
||||
}
|
||||
|
||||
std::string usage_report;
|
||||
CdmResponseType status = crypto_session_->GenerateUsageReport(
|
||||
provider_session_token_, &usage_report, &usage_duration_status,
|
||||
|
||||
@@ -29,14 +29,15 @@ RSA* GetKey(const std::string& serialized_key) {
|
||||
return NULL;
|
||||
}
|
||||
RSA* key = d2i_RSAPublicKey_bio(bio, NULL);
|
||||
BIO_free(bio);
|
||||
|
||||
if (key == NULL) {
|
||||
LOGE("GetKey: RSA key deserialization failure: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
BIO_free(bio);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "crypto_session.h"
|
||||
#include "license.h"
|
||||
#include "log.h"
|
||||
#include "metrics_group.h"
|
||||
|
||||
namespace {
|
||||
std::string kEmptyString;
|
||||
@@ -12,78 +13,65 @@ std::string kEmptyString;
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
UsageTableHeader* UsageTableHeader::usage_table_header_l1_ = NULL;
|
||||
UsageTableHeader* UsageTableHeader::usage_table_header_l3_ = NULL;
|
||||
|
||||
Lock UsageTableHeader::initialization_lock_;
|
||||
|
||||
UsageTableHeader* UsageTableHeader::GetInstance(FileSystem* file_system,
|
||||
CryptoSession* crypto_session) {
|
||||
LOGV("UsageTableHeader::GetInstance");
|
||||
AutoLock auto_lock(initialization_lock_);
|
||||
CdmSecurityLevel security_level = crypto_session->GetSecurityLevel();
|
||||
switch (security_level) {
|
||||
case kSecurityLevelL1:
|
||||
if (usage_table_header_l1_ != NULL)
|
||||
return usage_table_header_l1_;
|
||||
break;
|
||||
case kSecurityLevelL3:
|
||||
if (usage_table_header_l3_ != NULL)
|
||||
return usage_table_header_l3_;
|
||||
break;
|
||||
default:
|
||||
LOGE("UsageTableHeader::GetInstance: unsupported security level: %d",
|
||||
security_level);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UsageTableHeader* header =
|
||||
new UsageTableHeader(file_system, crypto_session, security_level);
|
||||
if (!header->is_inited()) {
|
||||
delete header;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (security_level == kSecurityLevelL1)
|
||||
usage_table_header_l1_ = header;
|
||||
else
|
||||
usage_table_header_l3_ = header;
|
||||
return header;
|
||||
UsageTableHeader::UsageTableHeader()
|
||||
: security_level_(kSecurityLevelUninitialized),
|
||||
requested_security_level_(kLevelDefault),
|
||||
is_inited_(false) {
|
||||
file_handle_.reset(new DeviceFiles(file_system_.get()));
|
||||
}
|
||||
|
||||
UsageTableHeader::UsageTableHeader(FileSystem* file_system,
|
||||
CryptoSession* crypto_session,
|
||||
CdmSecurityLevel security_level)
|
||||
: file_handle_(new DeviceFiles(file_system)),
|
||||
security_level_(security_level),
|
||||
is_inited_(false) {
|
||||
LOGV("UsageTableHeader::UsageTablerHeader: security level: %d",
|
||||
security_level);
|
||||
bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||
CryptoSession* crypto_session) {
|
||||
LOGV("UsageTableHeader::Init: security level: %d", security_level);
|
||||
if (crypto_session == NULL) {
|
||||
LOGE("UsageTableHeader::Init: no crypto session provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (security_level) {
|
||||
case kSecurityLevelL1:
|
||||
case kSecurityLevelL3:
|
||||
break;
|
||||
default:
|
||||
LOGE("UsageTableHeader::Init: invalid security level provided: %d",
|
||||
security_level);
|
||||
return false;
|
||||
}
|
||||
|
||||
security_level_ = security_level;
|
||||
|
||||
if (!file_handle_->Init(security_level)) {
|
||||
LOGE("UsageTableHeader::Init: device files initialization failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_handle_->RetrieveUsageTableInfo(&usage_table_header_,
|
||||
&usage_entry_info_)) {
|
||||
CdmResponseType status =
|
||||
crypto_session->CreateUsageTableHeader(&usage_table_header_);
|
||||
if (status != NO_ERROR) return;
|
||||
if (status != NO_ERROR) return false;
|
||||
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||
} else {
|
||||
CdmResponseType status =
|
||||
crypto_session->LoadUsageTableHeader(usage_table_header_);
|
||||
if (status != NO_ERROR) {
|
||||
LOGE(
|
||||
"UsageTableHeader::UsageTablerHeader: load usage table failed, "
|
||||
"security level: %d",
|
||||
"UsageTableHeader::Init: load usage table failed, security level: %d",
|
||||
security_level);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
requested_security_level_ =
|
||||
security_level_ == kSecurityLevelL3 ? kLevel3 : kLevelDefault;
|
||||
is_inited_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::AddEntry(
|
||||
CryptoSession* crypto_session, bool persistent_license,
|
||||
const CdmKeySetId& key_set_id, const std::string& usage_info_file_name,
|
||||
uint32_t* usage_entry_number) {
|
||||
LOGV("UsageTableHeader::AddEntry");
|
||||
LOGV("UsageTableHeader::AddEntry: Lock");
|
||||
AutoLock auto_lock(usage_table_header_lock_);
|
||||
CdmResponseType status = crypto_session->CreateUsageEntry(usage_entry_number);
|
||||
|
||||
@@ -101,7 +89,7 @@ CdmResponseType UsageTableHeader::AddEntry(
|
||||
size_t number_of_entries = usage_entry_info_.size();
|
||||
usage_entry_info_.resize(*usage_entry_number + 1);
|
||||
for (size_t i = number_of_entries; i < usage_entry_info_.size() - 1; ++i) {
|
||||
usage_entry_info_[i].storage_type = kStorageUnknown;
|
||||
usage_entry_info_[i].storage_type = kStorageTypeUnknown;
|
||||
usage_entry_info_[i].key_set_id.clear();
|
||||
usage_entry_info_[i].usage_info_file_name.clear();
|
||||
}
|
||||
@@ -120,15 +108,17 @@ CdmResponseType UsageTableHeader::AddEntry(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::LoadEntry(
|
||||
CryptoSession* crypto_session, const CdmUsageEntry& usage_entry,
|
||||
uint32_t usage_entry_number) {
|
||||
LOGV("UsageTableHeader::LoadEntry");
|
||||
CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session,
|
||||
const CdmUsageEntry& usage_entry,
|
||||
uint32_t usage_entry_number) {
|
||||
LOGV("UsageTableHeader::LoadEntry: Lock");
|
||||
AutoLock auto_lock(usage_table_header_lock_);
|
||||
|
||||
if (usage_entry_number >= usage_entry_info_.size()) {
|
||||
LOGE("UsageTableHeader::LoadEntry: usage entry number %d larger than table size: %d",
|
||||
usage_entry_number, usage_entry_info_.size());
|
||||
LOGE(
|
||||
"UsageTableHeader::LoadEntry: usage entry number %d larger than table "
|
||||
"size: %d",
|
||||
usage_entry_number, usage_entry_info_.size());
|
||||
return USAGE_INVALID_LOAD_ENTRY;
|
||||
}
|
||||
return crypto_session->LoadUsageEntry(usage_entry_number, usage_entry);
|
||||
@@ -136,20 +126,21 @@ CdmResponseType UsageTableHeader::LoadEntry(
|
||||
|
||||
CdmResponseType UsageTableHeader::UpdateEntry(CryptoSession* crypto_session,
|
||||
CdmUsageEntry* usage_entry) {
|
||||
LOGV("UsageTableHeader::UpdateEntry");
|
||||
LOGV("UsageTableHeader::UpdateEntryL: Lock");
|
||||
AutoLock auto_lock(usage_table_header_lock_);
|
||||
CdmUsageTableHeader usage_table_header;
|
||||
CdmResponseType status =
|
||||
crypto_session->UpdateUsageEntry(&usage_table_header_, usage_entry);
|
||||
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
file_handle_->StoreUsageTableInfo(usage_table_header, usage_entry_info_);
|
||||
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number) {
|
||||
LOGV("UsageTableHeader::DeleteEntry");
|
||||
CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number,
|
||||
DeviceFiles* handle,
|
||||
metrics::MetricsGroup* metrics) {
|
||||
LOGV("UsageTableHeader::DeleteEntry: Lock");
|
||||
AutoLock auto_lock(usage_table_header_lock_);
|
||||
if (usage_entry_number >= usage_entry_info_.size())
|
||||
return USAGE_INVALID_PARAMETERS_1;
|
||||
@@ -159,50 +150,67 @@ CdmResponseType UsageTableHeader::DeleteEntry(uint32_t usage_entry_number) {
|
||||
CdmUsageEntry swap_usage_entry;
|
||||
bool swap_usage_entry_valid = false;
|
||||
|
||||
for (; !swap_usage_entry_valid && swap_entry_number > usage_entry_number;
|
||||
--swap_entry_number) {
|
||||
while (!swap_usage_entry_valid && swap_entry_number > usage_entry_number) {
|
||||
switch (usage_entry_info_[swap_entry_number].storage_type) {
|
||||
case kStorageLicense:
|
||||
case kStorageUsageInfo: {
|
||||
CdmResponseType status = GetEntry(swap_entry_number, &swap_usage_entry);
|
||||
CdmResponseType status =
|
||||
GetEntry(swap_entry_number, handle, &swap_usage_entry);
|
||||
if (status == NO_ERROR) swap_usage_entry_valid = true;
|
||||
break;
|
||||
}
|
||||
case kStorageUnknown:
|
||||
case kStorageTypeUnknown:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!swap_usage_entry_valid) --swap_entry_number;
|
||||
}
|
||||
|
||||
uint32_t new_usage_table_size = 0;
|
||||
uint32_t number_of_entries_to_be_deleted =
|
||||
usage_entry_info_.size() - usage_entry_number;
|
||||
|
||||
if (swap_usage_entry_valid) {
|
||||
MoveEntry(swap_entry_number, swap_usage_entry, usage_entry_number);
|
||||
new_usage_table_size = swap_entry_number;
|
||||
} else {
|
||||
// No valid usage entries before entry to be deleted
|
||||
new_usage_table_size = usage_entry_number;
|
||||
CdmResponseType status = MoveEntry(swap_entry_number, swap_usage_entry,
|
||||
usage_entry_number, handle, metrics);
|
||||
// If unable to move entry, unset storage type of entry to be deleted and
|
||||
// resize |usage_entry_info_| so that swap usage entry is the last entry.
|
||||
if (status != NO_ERROR) {
|
||||
usage_entry_info_[usage_entry_number].storage_type = kStorageTypeUnknown;
|
||||
usage_entry_info_[usage_entry_number].key_set_id.clear();
|
||||
if (usage_entry_info_.size() - 1 == swap_entry_number) {
|
||||
file_handle_->StoreUsageTableInfo(usage_table_header_,
|
||||
usage_entry_info_);
|
||||
} else {
|
||||
Shrink(metrics, usage_entry_info_.size() - swap_entry_number - 1);
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
number_of_entries_to_be_deleted =
|
||||
usage_entry_info_.size() - swap_entry_number;
|
||||
}
|
||||
usage_entry_info_.resize(new_usage_table_size);
|
||||
CryptoSession crypto_session(&metrics_);
|
||||
crypto_session.Open(GetSecurityLevel());
|
||||
crypto_session.ShrinkUsageTableHeader(new_usage_table_size,
|
||||
&usage_table_header_);
|
||||
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||
return NO_ERROR;
|
||||
|
||||
return Shrink(metrics, number_of_entries_to_be_deleted);
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::MoveEntry(
|
||||
uint32_t from_usage_entry_number, const CdmUsageEntry& from_usage_entry,
|
||||
uint32_t to_usage_entry_number) {
|
||||
uint32_t to_usage_entry_number, DeviceFiles* handle,
|
||||
metrics::MetricsGroup* metrics) {
|
||||
LOGV("UsageTableHeader::MoveEntry");
|
||||
AutoLock auto_lock(usage_table_header_lock_);
|
||||
|
||||
CryptoSession crypto_session(&metrics_);
|
||||
crypto_session.Open(GetSecurityLevel());
|
||||
// crypto_session points to an object whose scope is this method or a test
|
||||
// object whose scope is the lifetime of this class
|
||||
scoped_ptr<CryptoSession> scoped_crypto_session;
|
||||
CryptoSession* crypto_session = test_crypto_session_.get();
|
||||
if (crypto_session == NULL) {
|
||||
scoped_crypto_session.reset((new CryptoSession(metrics)));
|
||||
crypto_session = scoped_crypto_session.get();
|
||||
}
|
||||
|
||||
crypto_session->Open(requested_security_level_);
|
||||
|
||||
CdmResponseType status =
|
||||
crypto_session.LoadUsageEntry(from_usage_entry_number, from_usage_entry);
|
||||
crypto_session->LoadUsageEntry(from_usage_entry_number, from_usage_entry);
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("UsageTableHeader::MoveEntry: Failed to load usage entry: %d",
|
||||
@@ -210,7 +218,7 @@ CdmResponseType UsageTableHeader::MoveEntry(
|
||||
return status;
|
||||
}
|
||||
|
||||
status = crypto_session.MoveUsageEntry(to_usage_entry_number);
|
||||
status = crypto_session->MoveUsageEntry(to_usage_entry_number);
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("UsageTableHeader::MoveEntry: Failed to move usage entry: %d->%d",
|
||||
@@ -222,7 +230,7 @@ CdmResponseType UsageTableHeader::MoveEntry(
|
||||
usage_entry_info_[from_usage_entry_number];
|
||||
|
||||
CdmUsageEntry usage_entry;
|
||||
status = crypto_session.UpdateUsageEntry(&usage_table_header_, &usage_entry);
|
||||
status = crypto_session->UpdateUsageEntry(&usage_table_header_, &usage_entry);
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("UsageTableHeader::MoveEntry: Failed to update usage entry: %d",
|
||||
@@ -232,12 +240,13 @@ CdmResponseType UsageTableHeader::MoveEntry(
|
||||
|
||||
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||
|
||||
StoreEntry(to_usage_entry_number, usage_entry);
|
||||
StoreEntry(to_usage_entry_number, handle, usage_entry);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||
DeviceFiles* handle,
|
||||
CdmUsageEntry* usage_entry) {
|
||||
uint32_t entry_number;
|
||||
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
||||
@@ -247,7 +256,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||
std::string key_renewal_response, release_server_url;
|
||||
int64_t playback_start_time, last_playback_time, grace_period_end_time;
|
||||
CdmAppParameterMap app_parameters;
|
||||
if (!file_handle_->RetrieveLicense(
|
||||
if (!handle->RetrieveLicense(
|
||||
usage_entry_info_[usage_entry_number].key_set_id, &license_state,
|
||||
&init_data, &key_request, &key_response, &key_renewal_request,
|
||||
&key_renewal_response, &release_server_url, &playback_start_time,
|
||||
@@ -263,7 +272,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||
CdmKeyMessage license_request;
|
||||
CdmKeyResponse license_response;
|
||||
|
||||
if (!file_handle_->RetrieveUsageInfoByKeySetId(
|
||||
if (!handle->RetrieveUsageInfoByKeySetId(
|
||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||
usage_entry_info_[usage_entry_number].key_set_id,
|
||||
&provider_session_token, &license_request, &license_response,
|
||||
@@ -274,7 +283,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kStorageUnknown:
|
||||
case kStorageTypeUnknown:
|
||||
default:
|
||||
LOGE(
|
||||
"UsageTableHeader::GetEntry: Attempting to retrieve usage "
|
||||
@@ -293,6 +302,7 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
DeviceFiles* handle,
|
||||
const CdmUsageEntry& usage_entry) {
|
||||
uint32_t entry_number;
|
||||
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
||||
@@ -303,7 +313,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
int64_t playback_start_time, last_playback_time, grace_period_end_time;
|
||||
CdmAppParameterMap app_parameters;
|
||||
CdmUsageEntry entry;
|
||||
if (!file_handle_->RetrieveLicense(
|
||||
if (!handle->RetrieveLicense(
|
||||
usage_entry_info_[usage_entry_number].key_set_id, &license_state,
|
||||
&init_data, &key_request, &key_response, &key_renewal_request,
|
||||
&key_renewal_response, &release_server_url, &playback_start_time,
|
||||
@@ -312,7 +322,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
LOGE("UsageTableHeader::StoreEntry: Failed to retrieve license");
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED;
|
||||
}
|
||||
if (!file_handle_->StoreLicense(
|
||||
if (!handle->StoreLicense(
|
||||
usage_entry_info_[usage_entry_number].key_set_id, license_state,
|
||||
init_data, key_request, key_response, key_renewal_request,
|
||||
key_renewal_response, release_server_url, playback_start_time,
|
||||
@@ -327,7 +337,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
CdmUsageEntry entry;
|
||||
std::string provider_session_token, init_data, key_request, key_response,
|
||||
key_renewal_request;
|
||||
if (!file_handle_->RetrieveUsageInfoByKeySetId(
|
||||
if (!handle->RetrieveUsageInfoByKeySetId(
|
||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||
usage_entry_info_[usage_entry_number].key_set_id,
|
||||
&provider_session_token, &key_request, &key_response, &entry,
|
||||
@@ -337,10 +347,10 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
"information");
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_USAGE_INFO_FAILED;
|
||||
}
|
||||
file_handle_->DeleteUsageInfo(
|
||||
handle->DeleteUsageInfo(
|
||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||
provider_session_token);
|
||||
if (!file_handle_->StoreUsageInfo(
|
||||
if (!handle->StoreUsageInfo(
|
||||
provider_session_token, key_request, key_response,
|
||||
usage_entry_info_[usage_entry_number].usage_info_file_name,
|
||||
usage_entry_info_[usage_entry_number].key_set_id, usage_entry,
|
||||
@@ -350,7 +360,7 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kStorageUnknown:
|
||||
case kStorageTypeUnknown:
|
||||
default:
|
||||
LOGE(
|
||||
"UsageTableHeader::GetUsageEntry: Attempting to retrieve usage "
|
||||
@@ -361,41 +371,56 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool UsageTableHeader::DeleteLastEntry() {
|
||||
CdmResponseType UsageTableHeader::Shrink(
|
||||
metrics::MetricsGroup* metrics,
|
||||
uint32_t number_of_usage_entries_to_delete) {
|
||||
if (usage_entry_info_.empty()) {
|
||||
LOGW(
|
||||
"UsageTableHeader::DeleteLastEntry: usage entry info table "
|
||||
"unexpectedly empty");
|
||||
return false;
|
||||
LOGE("UsageTableHeader::Shrink: usage entry info table unexpectedly empty");
|
||||
return NO_USAGE_ENTRIES;
|
||||
}
|
||||
|
||||
usage_entry_info_.resize(usage_entry_info_.size() - 1);
|
||||
if (usage_entry_info_.size() < number_of_usage_entries_to_delete) {
|
||||
LOGW(
|
||||
"UsageTableHeader::Shrink: cannot delete %d entries when usage entry "
|
||||
"table size is %d", number_of_usage_entries_to_delete,
|
||||
usage_entry_info_.size());
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
if (number_of_usage_entries_to_delete == 0) return NO_ERROR;
|
||||
|
||||
usage_entry_info_.resize(usage_entry_info_.size() -
|
||||
number_of_usage_entries_to_delete);
|
||||
|
||||
// crypto_session points to an object whose scope is this method or a test
|
||||
// object whose scope is the lifetime of this class
|
||||
scoped_ptr<CryptoSession> scoped_crypto_session;
|
||||
CryptoSession* crypto_session = test_crypto_session_.get();
|
||||
if (crypto_session == NULL) {
|
||||
scoped_crypto_session.reset((new CryptoSession(metrics)));
|
||||
crypto_session = scoped_crypto_session.get();
|
||||
}
|
||||
|
||||
CdmResponseType status = crypto_session->Open(requested_security_level_);
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
status = crypto_session->ShrinkUsageTableHeader(usage_entry_info_.size(),
|
||||
&usage_table_header_);
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
CryptoSession crypto_session(&metrics_);
|
||||
crypto_session.Open(GetSecurityLevel());
|
||||
crypto_session.ShrinkUsageTableHeader(usage_entry_info_.size(),
|
||||
&usage_table_header_);
|
||||
file_handle_->StoreUsageTableInfo(usage_table_header_, usage_entry_info_);
|
||||
return true;
|
||||
}
|
||||
|
||||
CdmResponseType UsageTableHeader::UpgradeFromUsageTable() {
|
||||
CryptoSession crypto_session(&metrics_);
|
||||
CdmResponseType status = crypto_session.Open(GetSecurityLevel());
|
||||
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
status = crypto_session.CreateUsageTableHeader(&usage_table_header_);
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
crypto_session.Close();
|
||||
|
||||
UpgradeLicensesFromUsageTable();
|
||||
UpgradeUsageInfoFromUsageTable();
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
||||
CdmResponseType UsageTableHeader::UpgradeFromUsageTable(
|
||||
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
|
||||
UpgradeLicensesFromUsageTable(handle, metrics);
|
||||
UpgradeUsageInfoFromUsageTable(handle, metrics);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool UsageTableHeader::UpgradeLicensesFromUsageTable(
|
||||
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
|
||||
// Fetch the key set IDs for each offline license. For each license
|
||||
// * retrieve the provider session token,
|
||||
// * create a new usage entry
|
||||
@@ -403,18 +428,14 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
||||
// * update the usage header table and entry numbers
|
||||
// * save the usage table header and store the usage entry number and
|
||||
// usage entry along with the license to persistent memory
|
||||
// On errors, continue to the next license, but indicate on return that not
|
||||
// all licenses may have been upgraded.
|
||||
std::vector<std::string> key_set_ids;
|
||||
if (file_handle_->ListLicenses(&key_set_ids)) {
|
||||
LOGE(
|
||||
if (handle->ListLicenses(&key_set_ids)) {
|
||||
LOGW(
|
||||
"UpgradeUsageTableHeader::UpgradeLicensesFromUsageTable: unable to "
|
||||
"retrieve list of licenses");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
|
||||
for (size_t i = 0; i < key_set_ids.size(); ++i) {
|
||||
DeviceFiles::LicenseState license_state;
|
||||
std::string init_data, key_request, key_response, key_renewal_request;
|
||||
@@ -423,7 +444,7 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
||||
CdmAppParameterMap app_parameters;
|
||||
CdmUsageEntry usage_entry;
|
||||
uint32_t usage_entry_number;
|
||||
if (!file_handle_->RetrieveLicense(
|
||||
if (!handle->RetrieveLicense(
|
||||
key_set_ids[i], &license_state, &init_data, &key_request,
|
||||
&key_response, &key_renewal_request, &key_renewal_response,
|
||||
&release_server_url, &playback_start_time, &last_playback_time,
|
||||
@@ -432,7 +453,6 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
||||
LOGW(
|
||||
"UsageTableHeader::UpgradeLicensesFromUsageTable: Failed to "
|
||||
"retrieve license");
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -442,37 +462,26 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
||||
LOGW(
|
||||
"UsageTableHeader::UpgradeLicensesFromUsageTable: Failed to "
|
||||
"retrieve provider session token");
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (provider_session_token.empty()) {
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
if (provider_session_token.empty()) continue;
|
||||
|
||||
CryptoSession crypto_session(&metrics_);
|
||||
CdmResponseType status = crypto_session.Open(GetSecurityLevel());
|
||||
CryptoSession crypto_session(metrics);
|
||||
CdmResponseType status = crypto_session.Open(requested_security_level_);
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
if (status != NO_ERROR) continue;
|
||||
|
||||
status = AddEntry(&crypto_session, true /* persistent license */,
|
||||
key_set_ids[i], kEmptyString, &usage_entry_number);
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
if (status != NO_ERROR) continue;
|
||||
|
||||
status = crypto_session.CopyOldUsageEntry(provider_session_token);
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
crypto_session.Close();
|
||||
DeleteLastEntry();
|
||||
result = false;
|
||||
Shrink(metrics, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -480,26 +489,27 @@ bool UsageTableHeader::UpgradeLicensesFromUsageTable() {
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
crypto_session.Close();
|
||||
DeleteLastEntry();
|
||||
result = false;
|
||||
Shrink(metrics, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!file_handle_->StoreLicense(
|
||||
if (!handle->StoreLicense(
|
||||
key_set_ids[i], license_state, init_data, key_request, key_response,
|
||||
key_renewal_request, key_renewal_response, release_server_url,
|
||||
playback_start_time, last_playback_time, grace_period_end_time,
|
||||
app_parameters, usage_entry, usage_entry_number)) {
|
||||
LOGW("UsageTableHeader::StoreEntry: Failed to store license");
|
||||
result = false;
|
||||
LOGE(
|
||||
"UsageTableHeader::UpgradeLicensesFromUsageTable: Failed to store "
|
||||
"license");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
||||
bool UsageTableHeader::UpgradeUsageInfoFromUsageTable(
|
||||
DeviceFiles* handle, metrics::MetricsGroup* metrics) {
|
||||
// Fetch all usage files. For each file retrieve all the usage info records
|
||||
// within the file. For each piece of usage information
|
||||
// * create a new usage entry
|
||||
@@ -509,27 +519,21 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
||||
// * once done processing all the usage records from a file, save the usage
|
||||
// information to persistent memory along with usage entry number and usage
|
||||
// entry.
|
||||
// On errors, continue to the next usage record, but indicate on return
|
||||
// that not all usage records may have been upgraded.
|
||||
std::vector<std::string> usage_info_file_names;
|
||||
if (file_handle_->ListUsageInfoFiles(&usage_info_file_names)) {
|
||||
LOGE(
|
||||
if (handle->ListUsageInfoFiles(&usage_info_file_names)) {
|
||||
LOGW(
|
||||
"UpgradeUsageTableHeader::UpgradeUsageInfoFromUsageTable: Unable to "
|
||||
"retrieve list of usage info file names");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
|
||||
for (size_t i = 0; i < usage_info_file_names.size(); ++i) {
|
||||
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
||||
if (!file_handle_->RetrieveUsageInfo(usage_info_file_names[i],
|
||||
&usage_data)) {
|
||||
if (!handle->RetrieveUsageInfo(usage_info_file_names[i], &usage_data)) {
|
||||
LOGW(
|
||||
"UsageTableHeader::UpgradeUsageInfoFromUsageTable: Failed to "
|
||||
"retrieve usage records from %s",
|
||||
usage_info_file_names[i].c_str());
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -538,17 +542,13 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
||||
LOGW(
|
||||
"UsageTableHeader::UpgradeUsageInfoFromUsageTable: Provider "
|
||||
"session id empty");
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
CryptoSession crypto_session(&metrics_);
|
||||
CdmResponseType status = crypto_session.Open(GetSecurityLevel());
|
||||
CryptoSession crypto_session(metrics);
|
||||
CdmResponseType status = crypto_session.Open(requested_security_level_);
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
if (status != NO_ERROR) continue;
|
||||
|
||||
// TODO(rfrias): We need to fill in the app id, but it is hashed
|
||||
// and we have no way to extract. Use the hased filename instead?
|
||||
@@ -556,18 +556,14 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
||||
usage_data[j].key_set_id, kEmptyString,
|
||||
&(usage_data[i].usage_entry_number));
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
if (status != NO_ERROR) continue;
|
||||
|
||||
status = crypto_session.CopyOldUsageEntry(
|
||||
usage_data[i].provider_session_token);
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
crypto_session.Close();
|
||||
DeleteLastEntry();
|
||||
result = false;
|
||||
Shrink(metrics, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -575,23 +571,21 @@ bool UsageTableHeader::UpgradeUsageInfoFromUsageTable() {
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
crypto_session.Close();
|
||||
DeleteLastEntry();
|
||||
result = false;
|
||||
Shrink(metrics, 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_handle_->StoreUsageInfo(usage_info_file_names[i], usage_data)) {
|
||||
LOGW(
|
||||
if (!handle->StoreUsageInfo(usage_info_file_names[i], usage_data)) {
|
||||
LOGE(
|
||||
"UsageTableHeader::StoreUsageInfo: Failed to store usage records to "
|
||||
"%s",
|
||||
usage_info_file_names[i].c_str());
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,9 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
|
||||
#include "usage_table_header.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
|
||||
#include "crypto_session.h"
|
||||
#include "device_files.h"
|
||||
#include "file_store.h"
|
||||
@@ -52,58 +50,10 @@ const CdmUsageEntryInfo kUsageEntryInfoStorageTypeUnknown = {
|
||||
.storage_type = kStorageTypeUnknown,
|
||||
.key_set_id = "",
|
||||
.usage_info_file_name = ""};
|
||||
|
||||
const std::vector<std::string> kEmptyLicenseList;
|
||||
|
||||
const std::string kLicenseArray[] = {
|
||||
kUsageEntryInfoOfflineLicense1.key_set_id,
|
||||
kUsageEntryInfoOfflineLicense2.key_set_id,
|
||||
kUsageEntryInfoOfflineLicense3.key_set_id,
|
||||
};
|
||||
const size_t kLicenseArraySize = sizeof(kLicenseArray)/
|
||||
sizeof(kLicenseArray[0]);
|
||||
std::vector<std::string> kLicenseList;
|
||||
|
||||
const std::vector<std::string> kEmptyUsageInfoFilesList;
|
||||
|
||||
const std::string kUsageInfoFileArray[] = {
|
||||
kUsageEntryInfoSecureStop1.usage_info_file_name,
|
||||
kUsageEntryInfoSecureStop2.usage_info_file_name,
|
||||
kUsageEntryInfoSecureStop3.usage_info_file_name,
|
||||
};
|
||||
const size_t kUsageInfoFileArraySize = sizeof(kUsageInfoFileArray)/
|
||||
sizeof(kUsageInfoFileArray[0]);
|
||||
std::vector<std::string> kUsageInfoFileList;
|
||||
|
||||
const DeviceFiles::CdmUsageData kCdmUsageData1 = {
|
||||
.provider_session_token = "provider_session_token_1",
|
||||
.license_request = "license_request_1",
|
||||
.license = "license_1",
|
||||
.key_set_id = "key_set_id_1",
|
||||
.usage_entry = "usage_entry_1",
|
||||
.usage_entry_number = 0,
|
||||
};
|
||||
const DeviceFiles::CdmUsageData kCdmUsageData2 = {
|
||||
.provider_session_token = "provider_session_token_2",
|
||||
.license_request = "license_request_2",
|
||||
.license = "license_2",
|
||||
.key_set_id = "key_set_id_2",
|
||||
.usage_entry = "usage_entry_2",
|
||||
.usage_entry_number = 0,
|
||||
};
|
||||
const DeviceFiles::CdmUsageData kCdmUsageData3 = {
|
||||
.provider_session_token = "provider_session_token_3",
|
||||
.license_request = "license_request_3",
|
||||
.license = "license_3",
|
||||
.key_set_id = "key_set_id_3",
|
||||
.usage_entry = "usage_entry_3",
|
||||
.usage_entry_number = 0,
|
||||
};
|
||||
const std::vector<DeviceFiles::CdmUsageData> kEmptyUsageInfoUsageDataList;
|
||||
|
||||
const std::vector<CdmUsageEntryInfo> kEmptyUsageEntryInfoVector;
|
||||
std::vector<CdmUsageEntryInfo> kUsageEntryInfoVector;
|
||||
|
||||
const std::vector<CdmUsageEntryInfo> kUsageEntryInfoVector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1,
|
||||
kUsageEntryInfoStorageTypeUnknown};
|
||||
const DeviceFiles::LicenseState kActiveLicenseState =
|
||||
DeviceFiles::kLicenseStateActive;
|
||||
const CdmInitData kPsshData = "pssh data";
|
||||
@@ -118,36 +68,6 @@ int64_t kPlaybackStartTime = 1030005;
|
||||
int64_t kPlaybackDuration = 300;
|
||||
int64_t kGracePeriodEndTime = 60;
|
||||
|
||||
namespace {
|
||||
|
||||
void InitVectorConstants() {
|
||||
kUsageEntryInfoVector.clear();
|
||||
kUsageEntryInfoVector.push_back(kUsageEntryInfoOfflineLicense1);
|
||||
kUsageEntryInfoVector.push_back(kUsageEntryInfoSecureStop1);
|
||||
kUsageEntryInfoVector.push_back(kUsageEntryInfoStorageTypeUnknown);
|
||||
|
||||
kUsageInfoFileList.clear();
|
||||
for (size_t i = 0; i < kUsageInfoFileArraySize; i++) {
|
||||
kUsageInfoFileList.push_back(kUsageInfoFileArray[i]);
|
||||
}
|
||||
|
||||
kLicenseList.clear();
|
||||
for (size_t i = 0; i < kLicenseArraySize; i++) {
|
||||
kLicenseList.push_back(kLicenseArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ToVector(std::vector<CdmUsageEntryInfo>& vec,
|
||||
const CdmUsageEntryInfo* arr, size_t total_size) {
|
||||
size_t max = total_size / sizeof(CdmUsageEntryInfo);
|
||||
vec.clear();
|
||||
for (size_t i = 0; i < max; i++) {
|
||||
vec.push_back(arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
|
||||
class MockDeviceFiles : public DeviceFiles {
|
||||
public:
|
||||
MockDeviceFiles() : DeviceFiles(&file_system_) { Init(kSecurityLevelL1); }
|
||||
@@ -162,17 +82,12 @@ class MockDeviceFiles : public DeviceFiles {
|
||||
bool(const std::string&, const std::string&, std::string*,
|
||||
CdmKeyMessage*, CdmKeyResponse*, CdmUsageEntry*,
|
||||
uint32_t*));
|
||||
MOCK_METHOD0(DeleteAllLicenses, bool());
|
||||
MOCK_METHOD7(StoreUsageInfo,
|
||||
bool(const std::string&, const CdmKeyMessage&,
|
||||
const CdmKeyResponse&, const std::string&,
|
||||
const std::string&, const CdmUsageEntry&, uint32_t));
|
||||
MOCK_METHOD2(RetrieveUsageInfo,
|
||||
bool(const std::string&, std::vector<CdmUsageData>*));
|
||||
MOCK_METHOD1(ListLicenses,
|
||||
bool(std::vector<std::string>* key_set_ids));
|
||||
MOCK_METHOD1(ListUsageInfoFiles,
|
||||
bool(std::vector<std::string>* usage_info_files));
|
||||
|
||||
private:
|
||||
FileSystem file_system_;
|
||||
@@ -180,8 +95,7 @@ class MockDeviceFiles : public DeviceFiles {
|
||||
|
||||
class MockCryptoSession : public CryptoSession {
|
||||
public:
|
||||
MockCryptoSession(metrics::CryptoMetrics* metrics)
|
||||
: CryptoSession(metrics) {}
|
||||
MockCryptoSession() : CryptoSession(NULL) {}
|
||||
MOCK_METHOD1(Open, CdmResponseType(SecurityLevel));
|
||||
MOCK_METHOD1(LoadUsageTableHeader,
|
||||
CdmResponseType(const CdmUsageTableHeader&));
|
||||
@@ -207,16 +121,11 @@ using ::testing::UnorderedElementsAre;
|
||||
using ::testing::UnorderedElementsAreArray;
|
||||
|
||||
class UsageTableHeaderTest : public ::testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase() {
|
||||
InitVectorConstants();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
// UsageTableHeader will take ownership of the pointer
|
||||
device_files_ = new MockDeviceFiles();
|
||||
crypto_session_ = new MockCryptoSession(&crypto_metrics_);
|
||||
crypto_session_ = new MockCryptoSession();
|
||||
usage_table_header_ = new UsageTableHeader();
|
||||
|
||||
// usage_table_header_ object takes ownership of these objects
|
||||
@@ -242,7 +151,6 @@ class UsageTableHeaderTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
MockDeviceFiles* device_files_;
|
||||
metrics::CryptoMetrics crypto_metrics_;
|
||||
MockCryptoSession* crypto_session_;
|
||||
UsageTableHeader* usage_table_header_;
|
||||
};
|
||||
@@ -259,86 +167,21 @@ TEST_F(UsageTableHeaderTest, InitError) {
|
||||
|
||||
class UsageTableHeaderInitializationTest
|
||||
: public UsageTableHeaderTest,
|
||||
public ::testing::WithParamInterface<CdmSecurityLevel> {
|
||||
public:
|
||||
static void SetUpTestCase() {
|
||||
InitVectorConstants();
|
||||
}
|
||||
|
||||
};
|
||||
public ::testing::WithParamInterface<CdmSecurityLevel> {};
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, CreateUsageTableHeader) {
|
||||
std::vector<CdmUsageEntryInfo> empty_usage_entry_info;
|
||||
|
||||
EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyUsageTableHeader),
|
||||
SetArgPointee<1>(kEmptyUsageEntryInfoVector),
|
||||
Return(false)));
|
||||
EXPECT_CALL(*device_files_, ListLicenses(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyLicenseList),
|
||||
Return(false)));
|
||||
EXPECT_CALL(*device_files_, ListUsageInfoFiles(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyUsageInfoFilesList),
|
||||
Return(false)));
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, Upgrade_UnableToRetrieveLicenses) {
|
||||
EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyUsageTableHeader),
|
||||
SetArgPointee<1>(kEmptyUsageEntryInfoVector),
|
||||
Return(false)));
|
||||
EXPECT_CALL(*device_files_, ListLicenses(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kLicenseList),
|
||||
Return(true)));
|
||||
EXPECT_CALL(*device_files_, ListUsageInfoFiles(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyUsageInfoFilesList),
|
||||
Return(false)));
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
// TODO: Why not being called?
|
||||
//EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(true));
|
||||
|
||||
for (size_t i = 0; i < kLicenseList.size(); ++i)
|
||||
device_files_->DeleteLicense(kLicenseList[i]);
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
|
||||
TEST_P(UsageTableHeaderInitializationTest, Upgrade_UnableToRetrieveUsageInfo) {
|
||||
EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyUsageTableHeader),
|
||||
SetArgPointee<1>(kEmptyUsageEntryInfoVector),
|
||||
Return(false)));
|
||||
EXPECT_CALL(*device_files_, ListLicenses(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kEmptyLicenseList),
|
||||
Return(false)));
|
||||
EXPECT_CALL(*device_files_, ListUsageInfoFiles(NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageInfoFileList),
|
||||
Return(true)));
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.Times(2)
|
||||
.WillRepeatedly(Return(true));
|
||||
for (size_t i = 0; i < kUsageInfoFileList.size(); ++i) {
|
||||
EXPECT_CALL(*device_files_,
|
||||
RetrieveUsageInfo(kUsageInfoFileList[i], NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<1>(kEmptyUsageInfoUsageDataList),
|
||||
Return(false)));
|
||||
}
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(GetParam(), crypto_session_));
|
||||
}
|
||||
@@ -552,7 +395,7 @@ TEST_F(UsageTableHeaderTest, UpdateEntry) {
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_InvalidUsageEntryNumber) {
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, kUsageEntryInfoVector);
|
||||
uint32_t usage_entry_number = kUsageEntryInfoVector.size();
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_NE(NO_ERROR, usage_table_header_->DeleteEntry(
|
||||
usage_entry_number, device_files_, &metrics));
|
||||
@@ -576,17 +419,14 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_InvalidUsageEntryNumber) {
|
||||
//
|
||||
// # of usage entries 4 4
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_CryptoSessionError) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1,
|
||||
kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 1; // kUsageEntryInfoOfflineLicense2
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(
|
||||
@@ -615,17 +455,14 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_CryptoSessionError) {
|
||||
//
|
||||
// # of usage entries 4 3
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_LastOfflineEntry) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1,
|
||||
kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 1; // kUsageEntryInfoOfflineLicense2
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(
|
||||
@@ -663,17 +500,14 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastOfflineEntry) {
|
||||
//
|
||||
// # of usage entries 4 3
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntry) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1,
|
||||
kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoSecureStop2};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 1; // kUsageEntryInfoSecureStop2
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(
|
||||
@@ -716,19 +550,17 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntry) {
|
||||
// # of usage entries 5 2
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
DeleteEntry_LastOfflineEntriesHaveMissingLicenses) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2,
|
||||
kUsageEntryInfoOfflineLicense3};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense1
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
device_files_->DeleteAllLicenses();
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(
|
||||
*crypto_session_,
|
||||
@@ -768,18 +600,15 @@ TEST_F(UsageTableHeaderTest,
|
||||
//
|
||||
// # of usage entries 5 2
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntriesAreMissing) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2,
|
||||
kUsageEntryInfoSecureStop3};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop1
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(
|
||||
@@ -834,18 +663,15 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastSecureStopEntriesAreMissing) {
|
||||
// # of usage entries 5 2
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
DeleteEntry_LastOfflineEntriesHaveIncorrectUsageEntryNumber) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2,
|
||||
kUsageEntryInfoOfflineLicense3};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense1
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_TRUE(device_files_->StoreLicense(
|
||||
usage_entry_info_vector[usage_entry_info_vector.size() - 1].key_set_id,
|
||||
@@ -903,20 +729,17 @@ TEST_F(UsageTableHeaderTest,
|
||||
// # of usage entries 5 2
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
DeleteEntry_LastSecureStopEntriesHaveIncorrectUsageEntryNumber) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2,
|
||||
kUsageEntryInfoSecureStop3};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop1
|
||||
uint32_t usage_entry_number_after_deleted_entry =
|
||||
usage_entry_number_to_be_deleted + 1;
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(
|
||||
@@ -981,18 +804,15 @@ TEST_F(UsageTableHeaderTest,
|
||||
//
|
||||
// # of usage entries 7 4
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreStorageTypeUnknown) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoOfflineLicense1,
|
||||
kUsageEntryInfoOfflineLicense2, kUsageEntryInfoOfflineLicense3,
|
||||
kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoStorageTypeUnknown};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(
|
||||
@@ -1037,20 +857,17 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreStorageTypeUnknown) {
|
||||
// # of usage entries 5 5
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
DeleteEntry_LastEntryIsOffline_MoveOfflineEntryFailed) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2,
|
||||
kUsageEntryInfoOfflineLicense3};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense1
|
||||
uint32_t last_usage_entry_number =
|
||||
usage_entry_info_vector.size() - 1; // kUsageEntryInfoOfflineLicense3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_TRUE(device_files_->StoreLicense(
|
||||
usage_entry_info_vector[last_usage_entry_number].key_set_id,
|
||||
@@ -1106,20 +923,17 @@ TEST_F(UsageTableHeaderTest,
|
||||
// # of usage entries 5 5
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
DeleteEntry_LastEntryIsSecureStop_MoveSecureStopEntryFailed) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2,
|
||||
kUsageEntryInfoSecureStop3};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop1
|
||||
uint32_t last_usage_entry_number =
|
||||
usage_entry_info_vector.size() - 1; // kUsageEntryInfoSecureStop3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault)).WillOnce(Return(NO_ERROR));
|
||||
EXPECT_CALL(*crypto_session_,
|
||||
@@ -1182,21 +996,18 @@ TEST_F(UsageTableHeaderTest,
|
||||
// # of usage entries 7 5
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
DeleteEntry_LastEntriesAreOfflineAndUnknown_MoveOfflineEntryFailed) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2,
|
||||
kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoStorageTypeUnknown};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 5; // kUsageEntryInfoOfflineLicense1
|
||||
uint32_t last_valid_usage_entry_number =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_TRUE(device_files_->StoreLicense(
|
||||
usage_entry_info_vector[last_valid_usage_entry_number].key_set_id,
|
||||
@@ -1263,21 +1074,18 @@ TEST_F(UsageTableHeaderTest,
|
||||
// # of usage entries 7 5
|
||||
TEST_F(UsageTableHeaderTest,
|
||||
DeleteEntry_LastEntriesAreSecureStopAndUnknown_MoveOfflineEntryFailed) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2,
|
||||
kUsageEntryInfoSecureStop3, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoStorageTypeUnknown};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 5; // kUsageEntryInfoOfflineLicense1
|
||||
uint32_t last_valid_usage_entry_number =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault))
|
||||
.Times(2)
|
||||
@@ -1339,20 +1147,17 @@ TEST_F(UsageTableHeaderTest,
|
||||
//
|
||||
// # of usage entries 5 4
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsOffline) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2,
|
||||
kUsageEntryInfoOfflineLicense3};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense1
|
||||
uint32_t last_usage_entry_number =
|
||||
usage_entry_info_vector.size() - 1; // kUsageEntryInfoOfflineLicense3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_TRUE(device_files_->StoreLicense(
|
||||
usage_entry_info_vector[last_usage_entry_number].key_set_id,
|
||||
@@ -1456,20 +1261,17 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsOffline) {
|
||||
//
|
||||
// # of usage entries 5 4
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsSecureStop) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2,
|
||||
kUsageEntryInfoSecureStop3};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop1
|
||||
uint32_t last_usage_entry_number =
|
||||
usage_entry_info_vector.size() - 1; // kUsageEntryInfoSecureStop3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault))
|
||||
.Times(2)
|
||||
@@ -1558,21 +1360,18 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntryIsSecureStop) {
|
||||
//
|
||||
// # of usage entries 7 4
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreOfflineAndUnknknown) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoOfflineLicense2,
|
||||
kUsageEntryInfoOfflineLicense3, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoStorageTypeUnknown};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 5; // kUsageEntryInfoOfflineLicense1
|
||||
uint32_t last_valid_usage_entry_number =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoOfflineLicense3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_TRUE(device_files_->StoreLicense(
|
||||
usage_entry_info_vector[last_valid_usage_entry_number].key_set_id,
|
||||
@@ -1680,21 +1479,18 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreOfflineAndUnknknown) {
|
||||
//
|
||||
// # of usage entries 7 4
|
||||
TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreSecureStopAndUnknknown) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
const std::vector<CdmUsageEntryInfo> usage_entry_info_vector = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoSecureStop1, kUsageEntryInfoSecureStop2,
|
||||
kUsageEntryInfoSecureStop3, kUsageEntryInfoStorageTypeUnknown,
|
||||
kUsageEntryInfoStorageTypeUnknown};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
Init(kSecurityLevelL1, kUsageTableHeader, usage_entry_info_vector);
|
||||
uint32_t usage_entry_number_to_be_deleted =
|
||||
usage_entry_info_vector.size() - 5; // kUsageEntryInfoSecureStop1
|
||||
uint32_t last_valid_usage_entry_number =
|
||||
usage_entry_info_vector.size() - 3; // kUsageEntryInfoSecureStop3
|
||||
metrics::CryptoMetrics metrics;
|
||||
metrics::MetricsGroup metrics;
|
||||
|
||||
EXPECT_CALL(*crypto_session_, Open(kLevelDefault))
|
||||
.Times(2)
|
||||
@@ -1762,30 +1558,4 @@ TEST_F(UsageTableHeaderTest, DeleteEntry_LastEntriesAreSecureStopAndUnknknown) {
|
||||
device_files_, &metrics));
|
||||
}
|
||||
|
||||
// If the crypto session says the usage table header is stale, init should fail.
|
||||
TEST_F(UsageTableHeaderTest, StaleHeader) {
|
||||
std::vector<CdmUsageEntryInfo> usage_entry_info_vector;
|
||||
const CdmUsageEntryInfo usage_entry_info_array[] = {
|
||||
kUsageEntryInfoOfflineLicense1, kUsageEntryInfoSecureStop1,
|
||||
kUsageEntryInfoStorageTypeUnknown, kUsageEntryInfoOfflineLicense2};
|
||||
ToVector(usage_entry_info_vector, usage_entry_info_array,
|
||||
sizeof(usage_entry_info_array));
|
||||
|
||||
EXPECT_CALL(*device_files_, RetrieveUsageTableInfo(NotNull(), NotNull()))
|
||||
.WillOnce(DoAll(SetArgPointee<0>(kUsageTableHeader),
|
||||
SetArgPointee<1>(usage_entry_info_vector),
|
||||
Return(true)));
|
||||
EXPECT_CALL(*crypto_session_, LoadUsageTableHeader(kUsageTableHeader))
|
||||
.WillOnce(Return(LOAD_USAGE_HEADER_GENERATION_SKEW));
|
||||
EXPECT_CALL(*crypto_session_, CreateUsageTableHeader(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(kEmptyUsageTableHeader), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*device_files_, DeleteAllLicenses()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*device_files_, StoreUsageTableInfo(kEmptyUsageTableHeader,
|
||||
kEmptyUsageEntryInfoVector))
|
||||
.WillOnce(Return(true));
|
||||
|
||||
EXPECT_TRUE(usage_table_header_->Init(kSecurityLevelL1, crypto_session_));
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -160,6 +160,11 @@ CdmResponseType WvContentDecryptionModule::AddKey(
|
||||
CdmEngine* cdm_engine = session_id.empty() ? GetCdmForSessionId(*key_set_id)
|
||||
: GetCdmForSessionId(session_id);
|
||||
if (!cdm_engine) return SESSION_NOT_FOUND_3;
|
||||
// Save key_set_id, as CDM will return an empty key_set_id on release
|
||||
CdmKeySetId release_key_set_id;
|
||||
if (session_id.empty() && key_set_id != NULL) {
|
||||
release_key_set_id = *key_set_id;
|
||||
}
|
||||
CdmResponseType sts;
|
||||
M_TIME(
|
||||
sts = cdm_engine->AddKey(
|
||||
@@ -170,8 +175,8 @@ CdmResponseType WvContentDecryptionModule::AddKey(
|
||||
cdm_engine_add_key_,
|
||||
sts);
|
||||
if (sts == KEY_ADDED && session_id.empty()) { // license type release
|
||||
cdm_engine->CloseKeySetSession(*key_set_id);
|
||||
cdm_by_session_id_.erase(*key_set_id);
|
||||
cdm_engine->CloseKeySetSession(release_key_set_id);
|
||||
cdm_by_session_id_.erase(release_key_set_id);
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
@@ -377,7 +382,10 @@ CdmResponseType WvContentDecryptionModule::Decrypt(
|
||||
cdm_engine->GetMetrics(),
|
||||
cdm_engine_find_session_for_key_,
|
||||
status);
|
||||
if (!status) return KEY_NOT_FOUND_IN_SESSION;
|
||||
if (!status && parameters.is_encrypted) {
|
||||
LOGE("WvContentDecryptionModule::Decrypt: unable to find session");
|
||||
return KEY_NOT_FOUND_IN_SESSION;
|
||||
}
|
||||
}
|
||||
CdmResponseType sts;
|
||||
M_TIME(
|
||||
|
||||
@@ -71,6 +71,10 @@ 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_name := distribution_test
|
||||
test_src_dir := ../metrics/test
|
||||
include $(LOCAL_PATH)/unit-test.mk
|
||||
|
||||
@@ -983,6 +983,142 @@ TEST_F(WvCdmExtendedDurationTest, UsageOverflowTest) {
|
||||
}
|
||||
}
|
||||
|
||||
// This test verifies that sessions allocated internally during key release
|
||||
// message generation are deallocated after their time to live period expires
|
||||
// by timer events (if other sessions are open).
|
||||
TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnTimerEvent) {
|
||||
Unprovision();
|
||||
Provision();
|
||||
|
||||
// Leave session open to run the CDM timer
|
||||
CdmSessionId streaming_session_id;
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&streaming_session_id);
|
||||
|
||||
// override default settings unless configured through the command line
|
||||
std::string key_id;
|
||||
std::string client_auth;
|
||||
GetOfflineConfiguration(&key_id, &client_auth);
|
||||
|
||||
uint32_t initial_open_sessions =
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
|
||||
|
||||
uint32_t max_sessions =
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS);
|
||||
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
|
||||
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
decryptor_.CloseSession(session_id_);
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
|
||||
session_id_.clear();
|
||||
key_set_id_.clear();
|
||||
decryptor_.OpenSession(g_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);
|
||||
|
||||
uint32_t open_sessions =
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
|
||||
|
||||
EXPECT_GT(open_sessions, initial_open_sessions);
|
||||
|
||||
sleep(kMinute + kClockTolerance);
|
||||
|
||||
open_sessions =
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
|
||||
|
||||
EXPECT_EQ(open_sessions, initial_open_sessions);
|
||||
|
||||
session_id_.clear();
|
||||
GenerateKeyRelease(key_set_id);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
|
||||
decryptor_.CloseSession(streaming_session_id);
|
||||
}
|
||||
|
||||
// This test verifies that sessions allocated internally during key release
|
||||
// message generation are deallocated after their time to live period expires
|
||||
// when a new session is opened.
|
||||
TEST_F(WvCdmExtendedDurationTest, AutomatedOfflineSessionReleaseOnOpenSession) {
|
||||
Unprovision();
|
||||
Provision();
|
||||
|
||||
// override default settings unless configured through the command line
|
||||
std::string key_id;
|
||||
std::string client_auth;
|
||||
GetOfflineConfiguration(&key_id, &client_auth);
|
||||
|
||||
uint32_t initial_open_sessions =
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS);
|
||||
|
||||
uint32_t max_sessions =
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS);
|
||||
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(kOfflineClip4, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
|
||||
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
decryptor_.CloseSession(session_id_);
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
|
||||
session_id_.clear();
|
||||
key_set_id_.clear();
|
||||
decryptor_.OpenSession(g_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_);
|
||||
|
||||
EXPECT_GT(
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS),
|
||||
initial_open_sessions);
|
||||
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
EXPECT_GT(
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS),
|
||||
initial_open_sessions);
|
||||
|
||||
sleep(kMinute + kClockTolerance);
|
||||
|
||||
EXPECT_GT(
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS),
|
||||
initial_open_sessions);
|
||||
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
|
||||
EXPECT_GT(
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS),
|
||||
initial_open_sessions);
|
||||
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
EXPECT_EQ(
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS),
|
||||
initial_open_sessions);
|
||||
|
||||
session_id_.clear();
|
||||
GenerateKeyRelease(key_set_id);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(kUatLicenseServer, client_auth, false);
|
||||
}
|
||||
|
||||
// This test verifies that sessions allocated internally during
|
||||
// key release message generation are deallocated after their
|
||||
// time to live period expires.
|
||||
|
||||
@@ -986,7 +986,7 @@ class TestWvCdmHlsEventListener : public WvCdmEventListener {
|
||||
|
||||
class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
public:
|
||||
WvCdmRequestLicenseTest() {}
|
||||
WvCdmRequestLicenseTest() : license_type_(kLicenseTypeStreaming) {}
|
||||
~WvCdmRequestLicenseTest() {}
|
||||
|
||||
protected:
|
||||
@@ -1032,6 +1032,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
CdmClientPropertySet* property_set) {
|
||||
CdmKeyRequest key_request;
|
||||
std::string key_set_id;
|
||||
license_type_ = license_type;
|
||||
EXPECT_EQ(expected_response,
|
||||
decryptor_.GenerateKeyRequest(
|
||||
session_id_, key_set_id, init_data_type, init_data,
|
||||
@@ -1075,6 +1076,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
void GenerateKeyRelease(CdmKeySetId key_set_id,
|
||||
CdmClientPropertySet* property_set,
|
||||
CdmKeyMessage* key_msg) {
|
||||
license_type_ = kLicenseTypeRelease;
|
||||
CdmSessionId session_id;
|
||||
CdmInitData init_data;
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
@@ -1168,26 +1170,34 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
}
|
||||
|
||||
void VerifyKeyRequestResponse(const std::string& server_url,
|
||||
const std::string& client_auth,
|
||||
bool is_renewal) {
|
||||
const std::string& client_auth) {
|
||||
std::string response;
|
||||
VerifyKeyRequestResponse(server_url, client_auth, is_renewal, &response);
|
||||
VerifyKeyRequestResponse(server_url, client_auth, false);
|
||||
}
|
||||
|
||||
void VerifyUsageKeyRequestResponse(const std::string& server_url,
|
||||
const std::string& client_auth) {
|
||||
std::string response;
|
||||
VerifyKeyRequestResponse(server_url, client_auth, true);
|
||||
}
|
||||
|
||||
void VerifyKeyRequestResponse(const std::string& server_url,
|
||||
const std::string& client_auth, bool is_renewal,
|
||||
const std::string& client_auth,
|
||||
bool is_usage) {
|
||||
std::string response;
|
||||
VerifyKeyRequestResponse(server_url, client_auth, is_usage, &response);
|
||||
}
|
||||
|
||||
void VerifyKeyRequestResponse(const std::string& server_url,
|
||||
const std::string& client_auth,
|
||||
bool is_usage,
|
||||
std::string* response) {
|
||||
*response = GetKeyRequestResponse(server_url, client_auth);
|
||||
|
||||
if (is_renewal) {
|
||||
// TODO application makes a license request, CDM will renew the license
|
||||
// when appropriate
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, *response, &key_set_id_),
|
||||
wvcdm::KEY_ADDED);
|
||||
} else {
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, *response, &key_set_id_),
|
||||
wvcdm::KEY_ADDED);
|
||||
}
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, *response, &key_set_id_),
|
||||
wvcdm::KEY_ADDED);
|
||||
EXPECT_EQ(is_usage || license_type_ == kLicenseTypeOffline,
|
||||
key_set_id_.size() > 0);
|
||||
}
|
||||
|
||||
void Unprovision() {
|
||||
@@ -1295,6 +1305,7 @@ class WvCdmRequestLicenseTest : public WvCdmTestBase {
|
||||
CdmKeyMessage key_msg_;
|
||||
CdmSessionId session_id_;
|
||||
CdmKeySetId key_set_id_;
|
||||
CdmLicenseType license_type_;
|
||||
};
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, ProvisioningTest) {
|
||||
@@ -1608,7 +1619,7 @@ TEST_F(WvCdmRequestLicenseTest, ForceL3Test) {
|
||||
kDefaultCdmIdentifier, NULL,
|
||||
&session_id_));
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -1624,7 +1635,7 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeTest) {
|
||||
EXPECT_EQ(decryptor_.AddKey(session_id_, resp, &key_set_id_),
|
||||
wvcdm::NEED_KEY);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -1637,7 +1648,7 @@ TEST_F(WvCdmRequestLicenseTest, PrivacyModeWithServiceCertificateTest) {
|
||||
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
||||
NULL, &session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -1682,7 +1693,7 @@ TEST_F(WvCdmRequestLicenseTest, AddStreamingKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -1698,7 +1709,7 @@ TEST_F(WvCdmRequestLicenseTest, AddKeyOfflineTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -1714,7 +1725,7 @@ TEST_F(WvCdmRequestLicenseTest, RestoreOfflineKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
@@ -1739,7 +1750,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
@@ -1756,7 +1767,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeyTest) {
|
||||
key_set_id_.clear();
|
||||
GenerateKeyRelease(key_set_id);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) {
|
||||
@@ -1775,7 +1786,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
@@ -1793,7 +1804,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseOfflineKeySessionUsageDisabledTest) {
|
||||
CdmKeyMessage key_msg;
|
||||
GenerateKeyRelease(key_set_id, NULL, &key_msg);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
SignedMessage signed_message;
|
||||
EXPECT_TRUE(signed_message.ParseFromString(key_msg));
|
||||
@@ -1830,7 +1841,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
@@ -1858,7 +1869,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryOfflineKeyTest) {
|
||||
key_set_id_.clear();
|
||||
GenerateKeyRelease(key_set_id);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
|
||||
@@ -1900,7 +1911,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
||||
NULL, &session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline, &property_set);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
@@ -1928,7 +1939,7 @@ TEST_F(WvCdmRequestLicenseTest, ReleaseRetryL3OfflineKeyTest) {
|
||||
key_set_id_.clear();
|
||||
GenerateKeyRelease(key_set_id, &property_set, NULL);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
}
|
||||
|
||||
TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
|
||||
@@ -1943,7 +1954,7 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
@@ -1976,7 +1987,7 @@ TEST_F(WvCdmRequestLicenseTest, ExpiryOnReleaseOfflineKeyTest) {
|
||||
AllOf(Each(Pair(_, kKeyStatusExpired)), Not(IsEmpty())), false));
|
||||
GenerateKeyRelease(key_set_id);
|
||||
key_set_id_ = key_set_id;
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
decryptor_.CloseSession(restore_session_id);
|
||||
}
|
||||
|
||||
@@ -1995,7 +2006,7 @@ TEST_F(WvCdmRequestLicenseTest, AutomatedOfflineSessionReleaseTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
@@ -2029,7 +2040,7 @@ TEST_F(WvCdmRequestLicenseTest, AutomatedOfflineSessionReleaseTest) {
|
||||
open_sessions,
|
||||
QueryStatus(kLevelDefault, wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS));
|
||||
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
EXPECT_EQ(
|
||||
--open_sessions,
|
||||
@@ -2040,12 +2051,12 @@ TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewal) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
std::string license_server;
|
||||
GenerateRenewalRequest(kLicenseTypeStreaming, &license_server);
|
||||
if (license_server.empty()) license_server = g_license_server;
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth, true);
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -2058,7 +2069,7 @@ TEST_F(WvCdmRequestLicenseTest, StreamingLicenseRenewalProhibited) {
|
||||
"08011a0d7769646576696e655f746573" // pssh data
|
||||
"74221073747265616d696e675f636c69703131");
|
||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
std::string init_data;
|
||||
wvcdm::CdmAppParameterMap app_parameters;
|
||||
@@ -2084,12 +2095,12 @@ TEST_F(WvCdmRequestLicenseTest, OfflineLicenseRenewal) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
|
||||
std::string license_server;
|
||||
GenerateRenewalRequest(kLicenseTypeOffline, &license_server);
|
||||
if (license_server.empty()) license_server = g_license_server;
|
||||
VerifyKeyRequestResponse(license_server, client_auth, true);
|
||||
VerifyKeyRequestResponse(license_server, client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -2098,7 +2109,7 @@ TEST_F(WvCdmRequestLicenseTest, RemoveKeys) {
|
||||
kDefaultCdmIdentifier, NULL,
|
||||
&session_id_));
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
ASSERT_EQ(NO_ERROR, decryptor_.RemoveKeys(session_id_));
|
||||
ASSERT_EQ(NO_ERROR, decryptor_.CloseSession(session_id_));
|
||||
}
|
||||
@@ -2217,7 +2228,7 @@ TEST_P(WvCdmStreamingLicenseRenewalTest, WithClientId) {
|
||||
0u, license_renewal.encrypted_client_id().encrypted_client_id().size());
|
||||
}
|
||||
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth, true);
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -2359,7 +2370,7 @@ TEST_P(WvCdmOfflineLicenseReleaseTest, WithClientId) {
|
||||
0u, license_release.encrypted_client_id().encrypted_client_id().size());
|
||||
}
|
||||
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -2414,7 +2425,7 @@ TEST_P(WvCdmUsageTest, WithClientId) {
|
||||
&property_set);
|
||||
|
||||
std::string key_response;
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false,
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, true,
|
||||
&key_response);
|
||||
|
||||
// Validate signed license
|
||||
@@ -2519,7 +2530,7 @@ TEST_F(WvCdmRequestLicenseTest, UsageInfoRetryTest) {
|
||||
"747265616d696e675f636c697033");
|
||||
|
||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming, NULL);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyUsageKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||
CdmDecryptionParameters decryption_parameters(
|
||||
@@ -2611,7 +2622,12 @@ TEST_P(WvCdmUsageInfoTest, UsageInfo) {
|
||||
key_id.append(1, ch);
|
||||
|
||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming, property_set);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
|
||||
// TODO(rfrias): streaming_clip6 is a streaming license without a pst
|
||||
if (ch == '6')
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
else
|
||||
VerifyUsageKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||
CdmDecryptionParameters decryption_parameters(
|
||||
@@ -2691,7 +2707,12 @@ TEST_F(WvCdmRequestLicenseTest, UsageReleaseAllTest) {
|
||||
key_id.append(1, ch);
|
||||
|
||||
GenerateKeyRequest(key_id, kLicenseTypeStreaming, &property_set);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
|
||||
// TODO(rfrias): streaming_clip6 is a streaming license without a pst
|
||||
if (ch == '6')
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
else
|
||||
VerifyUsageKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||
CdmDecryptionParameters decryption_parameters(
|
||||
@@ -2779,7 +2800,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryKeyStatus) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
CdmQueryMap query_info;
|
||||
CdmQueryMap::iterator itr;
|
||||
@@ -3013,7 +3034,7 @@ TEST_F(WvCdmRequestLicenseTest, QueryOemCryptoSessionId) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
CdmQueryMap query_info;
|
||||
CdmQueryMap::iterator itr;
|
||||
@@ -3101,7 +3122,7 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
decryptor_.CloseSession(session_id_);
|
||||
@@ -3140,7 +3161,7 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
|
||||
if (security_level != kSecurityLevelL1) return;
|
||||
@@ -3165,7 +3186,7 @@ TEST_F(WvCdmRequestLicenseTest, SecurityLevelPathBackwardCompatibility) {
|
||||
kDefaultCdmIdentifier, NULL,
|
||||
&session_id_));
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -3173,7 +3194,7 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_OfflineLicenseDecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
/*
|
||||
// key 1, encrypted, 256b
|
||||
@@ -3227,7 +3248,7 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, NULL, kDefaultCdmIdentifier, NULL,
|
||||
&session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeOffline);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
CdmKeySetId key_set_id = key_set_id_;
|
||||
EXPECT_FALSE(key_set_id_.empty());
|
||||
decryptor_.CloseSession(session_id_);
|
||||
@@ -3289,7 +3310,7 @@ TEST_F(WvCdmRequestLicenseTest, DISABLED_RestoreOfflineLicenseDecryptionTest) {
|
||||
TEST_F(WvCdmRequestLicenseTest, KeyControlBlockDecryptionTest) {
|
||||
decryptor_.OpenSession(g_key_system, &session_id_);
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
DecryptionData data;
|
||||
|
||||
@@ -3355,7 +3376,7 @@ TEST_P(WvCdmSessionSharingTest, SessionSharingTest) {
|
||||
NULL, &session_id_);
|
||||
CdmSessionId gp_session_id_1 = session_id_;
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
// TODO(rfrias): Move content information to ConfigTestEnv
|
||||
std::string gp_client_auth2 =
|
||||
@@ -3369,7 +3390,7 @@ TEST_P(WvCdmSessionSharingTest, SessionSharingTest) {
|
||||
NULL, &session_id_);
|
||||
CdmSessionId gp_session_id_2 = session_id_;
|
||||
GenerateKeyRequest(gp_key_id2, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, gp_client_auth2, false);
|
||||
VerifyKeyRequestResponse(g_license_server, gp_client_auth2);
|
||||
|
||||
SubSampleInfo* data = session_sharing_info->sub_sample;
|
||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||
@@ -3414,7 +3435,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) {
|
||||
NULL, &session_id_);
|
||||
CdmSessionId session_id1 = session_id_;
|
||||
GenerateKeyRequest(init_data1, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
// TODO(rfrias): Move content information to ConfigTestEnv
|
||||
std::string gp_client_auth2 =
|
||||
@@ -3428,7 +3449,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) {
|
||||
NULL, &session_id_);
|
||||
CdmSessionId session_id2 = session_id_;
|
||||
GenerateKeyRequest(init_data2, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, gp_client_auth2, false);
|
||||
VerifyKeyRequestResponse(g_license_server, gp_client_auth2);
|
||||
|
||||
SubSampleInfo* data = &single_encrypted_sub_sample_short_expiry;
|
||||
|
||||
@@ -3450,7 +3471,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionSharingTest) {
|
||||
NULL, &session_id_);
|
||||
CdmSessionId session_id3 = session_id_;
|
||||
GenerateKeyRequest(init_data1, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
EXPECT_EQ(NO_ERROR, decryptor_.Decrypt(session_id1, data->validate_key_id,
|
||||
decryption_parameters));
|
||||
@@ -3475,7 +3496,7 @@ TEST_F(WvCdmRequestLicenseTest, DecryptionKeyExpiredTest) {
|
||||
&session_id_);
|
||||
if (data->retrieve_key) {
|
||||
GenerateKeyRequest(kCpKeyId, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||
@@ -3516,7 +3537,7 @@ TEST_F(WvCdmRequestLicenseTest, SessionKeyChangeNotificationTest) {
|
||||
"0801121030313233343536373839616263646566"); // pssh data
|
||||
|
||||
GenerateKeyRequest(kCpKeyId, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
@@ -3531,7 +3552,7 @@ TEST_P(WvCdmDecryptionTest, DecryptionTest) {
|
||||
&session_id_);
|
||||
if (data->retrieve_key) {
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(g_license_server, g_client_auth);
|
||||
}
|
||||
|
||||
uint32_t decrypt_sample_buffer_size = 0;
|
||||
@@ -3574,6 +3595,59 @@ INSTANTIATE_TEST_CASE_P(Cdm, WvCdmDecryptionTest,
|
||||
&switch_key_encrypted_sub_samples[0],
|
||||
&partial_encrypted_sub_samples[0]));
|
||||
|
||||
class WvCdmSessionSharingNoKeyTest
|
||||
: public WvCdmRequestLicenseTest,
|
||||
public ::testing::WithParamInterface<SubSampleInfo*> {};
|
||||
|
||||
TEST_P(WvCdmSessionSharingNoKeyTest, DecryptionTest) {
|
||||
SubSampleInfo* data = GetParam();
|
||||
|
||||
TestWvCdmClientPropertySet property_set;
|
||||
property_set.set_session_sharing_mode(true);
|
||||
|
||||
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
||||
NULL, &session_id_);
|
||||
CdmSessionId gp_session_id_1 = session_id_;
|
||||
GenerateKeyRequest(g_key_id, kLicenseTypeStreaming);
|
||||
|
||||
// TODO(rfrias): Move content information to ConfigTestEnv
|
||||
std::string gp_client_auth2 =
|
||||
"?source=YOUTUBE&video_id=z3S_NhwueaM&oauth=ya.gtsqawidevine";
|
||||
std::string gp_key_id2 = wvcdm::a2bs_hex(
|
||||
"000000347073736800000000" // blob size and pssh
|
||||
"edef8ba979d64acea3c827dcd51d21ed00000014" // Widevine system id
|
||||
"08011210bdf1cb4fffc6506b8b7945b0bd2917fb"); // pssh data
|
||||
|
||||
decryptor_.OpenSession(g_key_system, &property_set, kDefaultCdmIdentifier,
|
||||
NULL, &session_id_);
|
||||
CdmSessionId gp_session_id_2 = session_id_;
|
||||
GenerateKeyRequest(gp_key_id2, kLicenseTypeStreaming);
|
||||
|
||||
std::vector<uint8_t> decrypt_buffer(data->encrypt_data.size());
|
||||
CdmDecryptionParameters decryption_parameters(
|
||||
&data->key_id, &data->encrypt_data.front(), data->encrypt_data.size(),
|
||||
&data->iv, data->block_offset, &decrypt_buffer[0]);
|
||||
decryption_parameters.is_encrypted = data->is_encrypted;
|
||||
decryption_parameters.is_secure = data->is_secure;
|
||||
decryption_parameters.subsample_flags = data->subsample_flags;
|
||||
|
||||
EXPECT_EQ(data->is_encrypted ? KEY_NOT_FOUND_IN_SESSION : NO_ERROR,
|
||||
decryptor_.Decrypt(gp_session_id_2, data->validate_key_id,
|
||||
decryption_parameters));
|
||||
if (!data->is_encrypted) {
|
||||
EXPECT_TRUE(std::equal(data->decrypt_data.begin(), data->decrypt_data.end(),
|
||||
decrypt_buffer.begin()));
|
||||
}
|
||||
|
||||
decryptor_.CloseSession(gp_session_id_1);
|
||||
decryptor_.CloseSession(gp_session_id_2);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Cdm, WvCdmSessionSharingNoKeyTest,
|
||||
::testing::Values(&clear_sub_sample,
|
||||
&clear_sub_sample_no_key,
|
||||
&single_encrypted_sub_sample));
|
||||
|
||||
TEST(VersionNumberTest, VersionNumberChangeCanary) {
|
||||
char release_number[PROPERTY_VALUE_MAX];
|
||||
ASSERT_GT(property_get("ro.build.version.release", release_number, "Unknown"),
|
||||
@@ -3599,7 +3673,7 @@ TEST_F(WvCdmRequestLicenseTest, AddHlsStreamingKeyTest) {
|
||||
kLicenseTypeStreaming, NULL);
|
||||
//TODO(rfrias): Remove once we switch to git-on-borg
|
||||
std::string license_server = "https://proxy.uat.widevine.com/proxy";
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth);
|
||||
decryptor_.CloseSession(session_id_);
|
||||
}
|
||||
|
||||
@@ -3643,7 +3717,7 @@ TEST_P(WvHlsDecryptionTest, HlsDecryptionTest) {
|
||||
kLicenseTypeStreaming, NULL);
|
||||
//TODO(rfrias): Remove once we switch to git-on-borg
|
||||
std::string license_server = "https://proxy.uat.widevine.com/proxy";
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth);
|
||||
CdmKeyStatusMap key_status_map = listener.GetKeyStatusMap();
|
||||
EXPECT_EQ(1u, key_status_map.size());
|
||||
KeyId key_id = key_status_map.begin()->first;
|
||||
@@ -3697,7 +3771,7 @@ TEST_P(WvHlsFourCCBackwardCompatibilityTest, HlsDecryptionTest) {
|
||||
kLicenseTypeStreaming, NULL);
|
||||
//TODO(rfrias): Remove once we switch to git-on-borg
|
||||
std::string license_server = "https://proxy.uat.widevine.com/proxy";
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth, false);
|
||||
VerifyKeyRequestResponse(license_server, g_client_auth);
|
||||
CdmKeyStatusMap key_status_map = listener.GetKeyStatusMap();
|
||||
EXPECT_EQ(1u, key_status_map.size());
|
||||
KeyId key_id = key_status_map.begin()->first;
|
||||
|
||||
@@ -476,7 +476,7 @@ status_t WVDrmPlugin::getPropertyString(const String8& name,
|
||||
if (name == "vendor") {
|
||||
value = "Google";
|
||||
} else if (name == "version") {
|
||||
value = "1.0";
|
||||
return queryProperty(QUERY_KEY_WVCDM_VERSION, value);
|
||||
} else if (name == "description") {
|
||||
value = "Widevine CDM";
|
||||
} else if (name == "algorithms") {
|
||||
@@ -519,6 +519,10 @@ status_t WVDrmPlugin::getPropertyString(const String8& name,
|
||||
value = mPropertySet.app_id().c_str();
|
||||
} else if (name == "origin") {
|
||||
value = mCdmIdentifier.origin.c_str();
|
||||
} else if (name == "CurrentSRMVersion") {
|
||||
return queryProperty(QUERY_KEY_CURRENT_SRM_VERSION, value);
|
||||
} else if (name == "SRMUpdateSupport") {
|
||||
return queryProperty(QUERY_KEY_SRM_UPDATE_SUPPORT, value);
|
||||
} else {
|
||||
ALOGE("App requested unknown string property %s", name.string());
|
||||
return android::ERROR_DRM_CANNOT_HANDLE;
|
||||
@@ -1005,6 +1009,11 @@ status_t WVDrmPlugin::mapOEMCryptoResult(OEMCryptoResult res) {
|
||||
bool WVDrmPlugin::initDataResemblesPSSH(const Vector<uint8_t>& initData) {
|
||||
const uint8_t* const initDataArray = initData.array();
|
||||
|
||||
if (sizeof(uint32_t) + kPsshTag.size() > initData.size()) {
|
||||
// The init data is so small that it couldn't contain a size and PSSH tag.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract the size field
|
||||
const uint8_t* const sizeField = &initDataArray[0];
|
||||
uint32_t nboSize;
|
||||
|
||||
@@ -93,6 +93,7 @@ using wvcdm::KEY_ID_SIZE;
|
||||
using wvcdm::KEY_IV_SIZE;
|
||||
using wvcdm::KEY_SET_ID_PREFIX;
|
||||
using wvcdm::NEVER_EXPIRES;
|
||||
using wvcdm::QUERY_KEY_CURRENT_SRM_VERSION;
|
||||
using wvcdm::QUERY_KEY_DEVICE_ID;
|
||||
using wvcdm::QUERY_KEY_MAX_NUMBER_OF_SESSIONS;
|
||||
using wvcdm::QUERY_KEY_NUMBER_OF_OPEN_SESSIONS;
|
||||
@@ -100,7 +101,9 @@ using wvcdm::QUERY_KEY_OEMCRYPTO_API_VERSION;
|
||||
using wvcdm::QUERY_KEY_OEMCRYPTO_SESSION_ID;
|
||||
using wvcdm::QUERY_KEY_PROVISIONING_ID;
|
||||
using wvcdm::QUERY_KEY_SECURITY_LEVEL;
|
||||
using wvcdm::QUERY_KEY_SRM_UPDATE_SUPPORT;
|
||||
using wvcdm::QUERY_KEY_SYSTEM_ID;
|
||||
using wvcdm::QUERY_KEY_WVCDM_VERSION;
|
||||
using wvcdm::QUERY_VALUE_SECURITY_LEVEL_L1;
|
||||
using wvcdm::QUERY_VALUE_SECURITY_LEVEL_L3;
|
||||
using wvcdm::SecurityLevel;
|
||||
@@ -1045,6 +1048,11 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
static const std::string maxSessions = "54";
|
||||
static const std::string oemCryptoApiVersion = "13";
|
||||
|
||||
static const std::string currentSRMVersion = "1";
|
||||
static const std::string cdmVersion = "Infinity Minus 1";
|
||||
std::string serializedMetrics(
|
||||
kSerializedMetrics, kSerializedMetrics + sizeof(kSerializedMetrics));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1),
|
||||
testing::Return(wvcdm::NO_ERROR)))
|
||||
@@ -1075,6 +1083,21 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
.WillOnce(DoAll(SetArgPointee<2>(oemCryptoApiVersion),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SRM_UPDATE_SUPPORT, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>("True"),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_CURRENT_SRM_VERSION, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(currentSRMVersion),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_WVCDM_VERSION, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(cdmVersion),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, GetSerializedMetrics(_))
|
||||
.WillOnce(SetArgPointee<0>(serializedMetrics));
|
||||
|
||||
WVDrmPlugin plugin(cdm.get(), appPackageName, &crypto, false);
|
||||
std::string stringResult;
|
||||
std::vector<uint8_t> vectorResult;
|
||||
@@ -1088,7 +1111,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
plugin.getPropertyString(
|
||||
hidl_string("version"), [&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ("1.0", stringResult.c_str());
|
||||
EXPECT_STREQ(cdmVersion.c_str(), stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
@@ -1159,7 +1182,21 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
hidl_string("oemCryptoApiVersion"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_EQ(oemCryptoApiVersion, stringResult.c_str());
|
||||
EXPECT_STREQ(oemCryptoApiVersion.c_str(), stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("SRMUpdateSupport"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ("True", stringResult.c_str());
|
||||
});
|
||||
|
||||
plugin.getPropertyString(
|
||||
hidl_string("CurrentSRMVersion"),
|
||||
[&](Status status, hidl_string stringResult) {
|
||||
ASSERT_EQ(Status::OK, status);
|
||||
EXPECT_STREQ(currentSRMVersion.c_str(), stringResult.c_str());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -838,6 +838,11 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
static const string maxSessions = "18";
|
||||
static const string oemCryptoApiVersion = "10";
|
||||
|
||||
static const string currentSRMVersion = "1";
|
||||
static const string cdmVersion = "Infinity Minus 1";
|
||||
string serializedMetrics(kSerializedMetrics,
|
||||
kSerializedMetrics + sizeof(kSerializedMetrics));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SECURITY_LEVEL, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(QUERY_VALUE_SECURITY_LEVEL_L1),
|
||||
Return(wvcdm::NO_ERROR)))
|
||||
@@ -868,6 +873,21 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
.WillOnce(DoAll(SetArgPointee<2>(oemCryptoApiVersion),
|
||||
Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_SRM_UPDATE_SUPPORT, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>("True"),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_CURRENT_SRM_VERSION, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(currentSRMVersion),
|
||||
testing::Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, QueryStatus(_, QUERY_KEY_WVCDM_VERSION, _))
|
||||
.WillOnce(DoAll(SetArgPointee<2>(cdmVersion),
|
||||
Return(wvcdm::NO_ERROR)));
|
||||
|
||||
EXPECT_CALL(*cdm, GetSerializedMetrics(_))
|
||||
.WillOnce(SetArgPointee<0>(serializedMetrics));
|
||||
|
||||
String8 stringResult;
|
||||
Vector<uint8_t> vectorResult;
|
||||
|
||||
@@ -877,7 +897,7 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
|
||||
res = plugin.getPropertyString(String8("version"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_STREQ("1.0", stringResult.string());
|
||||
EXPECT_STREQ(cdmVersion.c_str(), stringResult.string());
|
||||
|
||||
res = plugin.getPropertyString(String8("description"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
@@ -918,7 +938,22 @@ TEST_F(WVDrmPluginTest, ReturnsExpectedPropertyValues) {
|
||||
|
||||
res = plugin.getPropertyString(String8("oemCryptoApiVersion"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_EQ(oemCryptoApiVersion, stringResult.string());
|
||||
|
||||
EXPECT_STREQ(oemCryptoApiVersion.c_str(), stringResult.string());
|
||||
|
||||
res = plugin.getPropertyString(String8("SRMUpdateSupport"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_STREQ("True", stringResult.string());
|
||||
|
||||
res = plugin.getPropertyString(String8("CurrentSRMVersion"), stringResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_STREQ(currentSRMVersion.c_str(), stringResult.string());
|
||||
|
||||
vectorResult.clear();
|
||||
res = plugin.getPropertyByteArray(String8("metrics"), vectorResult);
|
||||
ASSERT_EQ(OK, res);
|
||||
EXPECT_THAT(vectorResult, ElementsAreArray(serializedMetrics.data(),
|
||||
serializedMetrics.size()));
|
||||
}
|
||||
|
||||
TEST_F(WVDrmPluginTest, DoesNotGetUnknownProperties) {
|
||||
|
||||
Reference in New Issue
Block a user