Merge "Merge of CLs"

This commit is contained in:
Rahul Frias
2015-09-26 01:19:24 +00:00
committed by Android (Google) Code Review
10 changed files with 71 additions and 48 deletions

View File

@@ -23,7 +23,8 @@ class WvCdmEventListener;
class CdmSession { class CdmSession {
public: public:
CdmSession(const CdmClientPropertySet* cdm_client_property_set, CdmSession(const CdmClientPropertySet* cdm_client_property_set,
const std::string& origin, WvCdmEventListener* event_listener); const std::string& origin, WvCdmEventListener* event_listener,
CdmSessionId* forced_session_id);
virtual ~CdmSession(); virtual ~CdmSession();
virtual CdmResponseType Init(); virtual CdmResponseType Init();

View File

@@ -4,6 +4,7 @@
#define WVCDM_CORE_DEVICE_FILES_H_ #define WVCDM_CORE_DEVICE_FILES_H_
#include <unistd.h> #include <unistd.h>
#include <set>
#include <string> #include <string>
#include "scoped_ptr.h" #include "scoped_ptr.h"
@@ -110,7 +111,6 @@ class DeviceFiles {
static std::string GetCertificateFileName(const std::string& origin); static std::string GetCertificateFileName(const std::string& origin);
static std::string GetLicenseFileNameExtension(); static std::string GetLicenseFileNameExtension();
static std::string GetUsageInfoFileName(const std::string& app_id); static std::string GetUsageInfoFileName(const std::string& app_id);
static std::string GetBlankFileData();
static std::string GetFileNameSafeHash(const std::string& input); static std::string GetFileNameSafeHash(const std::string& input);
// For testing only: // For testing only:
@@ -122,7 +122,7 @@ class DeviceFiles {
FRIEND_TEST(DeviceCertificateTest, HasCertificate); FRIEND_TEST(DeviceCertificateTest, HasCertificate);
FRIEND_TEST(DeviceFilesStoreTest, StoreLicense); FRIEND_TEST(DeviceFilesStoreTest, StoreLicense);
FRIEND_TEST(DeviceFilesTest, DeleteLicense); FRIEND_TEST(DeviceFilesTest, DeleteLicense);
FRIEND_TEST(DeviceFilesTest, ReserveLicenseIds); FRIEND_TEST(DeviceFilesTest, ReserveLicenseIdsDoesNotUseFileSystem);
FRIEND_TEST(DeviceFilesTest, RetrieveLicenses); FRIEND_TEST(DeviceFilesTest, RetrieveLicenses);
FRIEND_TEST(DeviceFilesTest, AppParametersBackwardCompatibility); FRIEND_TEST(DeviceFilesTest, AppParametersBackwardCompatibility);
FRIEND_TEST(DeviceFilesTest, SecurityLevelPathBackwardCompatibility); FRIEND_TEST(DeviceFilesTest, SecurityLevelPathBackwardCompatibility);
@@ -141,6 +141,8 @@ class DeviceFiles {
FRIEND_TEST(WvCdmExtendedDurationTest, UsageOverflowTest); FRIEND_TEST(WvCdmExtendedDurationTest, UsageOverflowTest);
#endif #endif
static std::set<std::string> reserved_license_ids_;
scoped_ptr<File> file_; scoped_ptr<File> file_;
CdmSecurityLevel security_level_; CdmSecurityLevel security_level_;
bool initialized_; bool initialized_;

View File

@@ -54,6 +54,7 @@ class Properties {
std::string* base_path); std::string* base_path);
static bool GetFactoryKeyboxPath(std::string* keybox); static bool GetFactoryKeyboxPath(std::string* keybox);
static bool GetOEMCryptoPath(std::string* library_name); static bool GetOEMCryptoPath(std::string* library_name);
static bool AlwaysUseKeySetIds();
static bool GetSecurityLevelDirectories(std::vector<std::string>* dirs); static bool GetSecurityLevelDirectories(std::vector<std::string>* dirs);
static bool GetApplicationId(const CdmSessionId& session_id, static bool GetApplicationId(const CdmSessionId& session_id,
std::string* app_id); std::string* app_id);

View File

@@ -91,8 +91,13 @@ CdmResponseType CdmEngine::OpenSession(const CdmKeySystem& key_system,
return INVALID_PARAMETERS_ENG_1; return INVALID_PARAMETERS_ENG_1;
} }
CdmSessionId* forced_session_id = NULL;
if (Properties::AlwaysUseKeySetIds() && !session_id->empty()) {
forced_session_id = session_id;
}
scoped_ptr<CdmSession> new_session( scoped_ptr<CdmSession> new_session(
new CdmSession(property_set, origin, event_listener)); new CdmSession(property_set, origin, event_listener, forced_session_id));
if (new_session->session_id().empty()) { if (new_session->session_id().empty()) {
LOGE("CdmEngine::OpenSession: failure to generate session ID"); LOGE("CdmEngine::OpenSession: failure to generate session ID");
return EMPTY_SESSION_ID; return EMPTY_SESSION_ID;
@@ -180,7 +185,10 @@ CdmResponseType CdmEngine::GenerateKeyRequest(
CdmSessionId id = session_id; CdmSessionId id = session_id;
CdmResponseType sts; CdmResponseType sts;
if (license_type == kLicenseTypeRelease) { // NOTE: If AlwaysUseKeySetIds() is true, there is no need to consult the
// release_key_sets_ map for release licenses.
if (license_type == kLicenseTypeRelease &&
!Properties::AlwaysUseKeySetIds()) {
if (key_set_id.empty()) { if (key_set_id.empty()) {
LOGE("CdmEngine::GenerateKeyRequest: invalid key set ID"); LOGE("CdmEngine::GenerateKeyRequest: invalid key set ID");
return EMPTY_KEYSET_ID_ENG_2; return EMPTY_KEYSET_ID_ENG_2;
@@ -666,7 +674,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
usage_property_set_->set_security_level(kLevelDefault); usage_property_set_->set_security_level(kLevelDefault);
usage_property_set_->set_app_id(app_id); usage_property_set_->set_app_id(app_id);
usage_session_.reset( usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL)); new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL, NULL));
CdmResponseType status = usage_session_->Init(); CdmResponseType status = usage_session_->Init();
if (NO_ERROR != status) { if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error"); LOGE("CdmEngine::GetUsageInfo: session init error");
@@ -685,7 +693,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
usage_property_set_->set_security_level(kLevel3); usage_property_set_->set_security_level(kLevel3);
usage_property_set_->set_app_id(app_id); usage_property_set_->set_app_id(app_id);
usage_session_.reset( usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL)); new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL, NULL));
status = usage_session_->Init(); status = usage_session_->Init();
if (NO_ERROR != status) { if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error"); LOGE("CdmEngine::GetUsageInfo: session init error");
@@ -754,7 +762,7 @@ CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
usage_property_set_->set_app_id(app_id); usage_property_set_->set_app_id(app_id);
usage_session_.reset( usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL)); new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL, NULL));
CdmResponseType status = usage_session_->Init(); CdmResponseType status = usage_session_->Init();
if (NO_ERROR != status) { if (NO_ERROR != status) {
@@ -833,7 +841,8 @@ CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
: kLevelDefault; : kLevelDefault;
usage_property_set_->set_security_level(security_level); usage_property_set_->set_security_level(security_level);
usage_session_.reset( usage_session_.reset(
new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL)); new CdmSession(usage_property_set_.get(), EMPTY_ORIGIN, NULL,
NULL));
CdmResponseType status2 = usage_session_-> CdmResponseType status2 = usage_session_->
DeleteMultipleUsageInformation(provider_session_tokens); DeleteMultipleUsageInformation(provider_session_tokens);
if (status2 != NO_ERROR) { if (status2 != NO_ERROR) {

View File

@@ -25,14 +25,13 @@ namespace wvcdm {
CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set, CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set,
const std::string& origin, const std::string& origin,
WvCdmEventListener* event_listener) WvCdmEventListener* event_listener,
CdmSessionId* forced_session_id)
: initialized_(false), : initialized_(false),
session_id_(GenerateSessionId()), session_id_(GenerateSessionId()),
origin_(origin), origin_(origin),
license_parser_(new CdmLicense), license_parser_(new CdmLicense),
crypto_session_(new CryptoSession), crypto_session_(new CryptoSession),
policy_engine_(
new PolicyEngine(session_id_, event_listener, crypto_session_.get())),
file_handle_(new DeviceFiles), file_handle_(new DeviceFiles),
license_received_(false), license_received_(false),
is_offline_(false), is_offline_(false),
@@ -43,6 +42,17 @@ CdmSession::CdmSession(const CdmClientPropertySet* cdm_client_property_set,
has_decrypted_since_last_report_(false), has_decrypted_since_last_report_(false),
is_initial_usage_update_(true), is_initial_usage_update_(true),
is_usage_update_needed_(false) { is_usage_update_needed_(false) {
if (Properties::AlwaysUseKeySetIds()) {
if (forced_session_id) {
key_set_id_ = *forced_session_id;
} else {
bool ok = GenerateKeySetId(&key_set_id_);
assert(ok);
}
session_id_ = key_set_id_;
}
policy_engine_.reset(new PolicyEngine(
session_id_, event_listener, crypto_session_.get()));
if (cdm_client_property_set) { if (cdm_client_property_set) {
if (cdm_client_property_set->security_level() == if (cdm_client_property_set->security_level() ==
QUERY_VALUE_SECURITY_LEVEL_L3) { QUERY_VALUE_SECURITY_LEVEL_L3) {
@@ -203,7 +213,8 @@ CdmResponseType CdmSession::GenerateKeyRequest(
LOGW("CdmSession::GenerateKeyRequest: init data absent"); LOGW("CdmSession::GenerateKeyRequest: init data absent");
return INIT_DATA_NOT_FOUND; return INIT_DATA_NOT_FOUND;
} }
if (is_offline_ && !GenerateKeySetId(&key_set_id_)) { if (is_offline_ && key_set_id_.empty() &&
!GenerateKeySetId(&key_set_id_)) {
LOGE("CdmSession::GenerateKeyRequest: Unable to generate key set ID"); LOGE("CdmSession::GenerateKeyRequest: Unable to generate key set ID");
return KEY_REQUEST_ERROR_1; return KEY_REQUEST_ERROR_1;
} }

View File

@@ -46,8 +46,6 @@ const char* kSecurityLevelPathCompatibilityExclusionList[] = {
size_t kSecurityLevelPathCompatibilityExclusionListSize = size_t kSecurityLevelPathCompatibilityExclusionListSize =
sizeof(kSecurityLevelPathCompatibilityExclusionList) / sizeof(kSecurityLevelPathCompatibilityExclusionList) /
sizeof(*kSecurityLevelPathCompatibilityExclusionList); sizeof(*kSecurityLevelPathCompatibilityExclusionList);
// Some platforms cannot store a truly blank file, so we use a W for Widevine.
const char kBlankFileData[] = "W";
bool Hash(const std::string& data, std::string* hash) { bool Hash(const std::string& data, std::string* hash) {
if (!hash) return false; if (!hash) return false;
@@ -64,6 +62,9 @@ bool Hash(const std::string& data, std::string* hash) {
namespace wvcdm { namespace wvcdm {
// static
std::set<std::string> DeviceFiles::reserved_license_ids_;
DeviceFiles::DeviceFiles() DeviceFiles::DeviceFiles()
: file_(NULL), : file_(NULL),
security_level_(kSecurityLevelUninitialized), security_level_(kSecurityLevelUninitialized),
@@ -228,6 +229,7 @@ bool DeviceFiles::StoreLicense(
std::string serialized_file; std::string serialized_file;
file.SerializeToString(&serialized_file); file.SerializeToString(&serialized_file);
reserved_license_ids_.erase(key_set_id);
return StoreFileWithHash(key_set_id + kLicenseFileNameExt, serialized_file); return StoreFileWithHash(key_set_id + kLicenseFileNameExt, serialized_file);
} }
@@ -331,6 +333,8 @@ bool DeviceFiles::LicenseExists(const std::string& key_set_id) {
return false; return false;
} }
return FileExists(key_set_id + kLicenseFileNameExt); return FileExists(key_set_id + kLicenseFileNameExt);
return reserved_license_ids_.count(key_set_id) ||
FileExists(key_set_id + kLicenseFileNameExt);
} }
bool DeviceFiles::ReserveLicenseId(const std::string& key_set_id) { bool DeviceFiles::ReserveLicenseId(const std::string& key_set_id) {
@@ -338,7 +342,8 @@ bool DeviceFiles::ReserveLicenseId(const std::string& key_set_id) {
LOGW("DeviceFiles::ReserveLicenseId: not initialized"); LOGW("DeviceFiles::ReserveLicenseId: not initialized");
return false; return false;
} }
return StoreFileRaw(key_set_id + kLicenseFileNameExt, kBlankFileData); reserved_license_ids_.insert(key_set_id);
return true;
} }
bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token, bool DeviceFiles::StoreUsageInfo(const std::string& provider_session_token,
@@ -804,8 +809,6 @@ std::string DeviceFiles::GetUsageInfoFileName(const std::string& app_id) {
return kUsageInfoFileNamePrefix + hash + kUsageInfoFileNameExt; return kUsageInfoFileNamePrefix + hash + kUsageInfoFileNameExt;
} }
std::string DeviceFiles::GetBlankFileData() { return kBlankFileData; }
std::string DeviceFiles::GetFileNameSafeHash(const std::string& input) { std::string DeviceFiles::GetFileNameSafeHash(const std::string& input) {
std::vector<uint8_t> hash(MD5_DIGEST_LENGTH); std::vector<uint8_t> hash(MD5_DIGEST_LENGTH);
const unsigned char* input_ptr = const unsigned char* input_ptr =

View File

@@ -1,7 +1,7 @@
// Copyright 2013 Google Inc. All Rights Reserved. // Copyright 2013 Google Inc. All Rights Reserved.
#include "log.h" #include "log.h"
#include "properties_configuration.h" #include "properties.h"
#include "wv_cdm_constants.h" #include "wv_cdm_constants.h"
namespace { namespace {
@@ -16,17 +16,6 @@ bool Properties::use_certificates_as_identification_;
bool Properties::security_level_path_backward_compatibility_support_; bool Properties::security_level_path_backward_compatibility_support_;
scoped_ptr<CdmClientPropertySetMap> Properties::session_property_set_; scoped_ptr<CdmClientPropertySetMap> Properties::session_property_set_;
void Properties::Init() {
oem_crypto_use_secure_buffers_ = kPropertyOemCryptoUseSecureBuffers;
oem_crypto_use_fifo_ = kPropertyOemCryptoUseFifo;
oem_crypto_use_userspace_buffers_ = kPropertyOemCryptoUseUserSpaceBuffers;
use_certificates_as_identification_ =
kPropertyUseCertificatesAsIdentification;
security_level_path_backward_compatibility_support_ =
kSecurityLevelPathBackwardCompatibilitySupport;
session_property_set_.reset(new CdmClientPropertySetMap());
}
bool Properties::AddSessionPropertySet( bool Properties::AddSessionPropertySet(
const CdmSessionId& session_id, const CdmClientPropertySet* property_set) { const CdmSessionId& session_id, const CdmClientPropertySet* property_set) {
if (NULL == session_property_set_.get()) { if (NULL == session_property_set_.get()) {

View File

@@ -132,7 +132,7 @@ class MockCdmLicense : public CdmLicense {
class CdmSessionTest : public ::testing::Test { class CdmSessionTest : public ::testing::Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {
cdm_session_.reset(new CdmSession(NULL, kTestOrigin, NULL)); cdm_session_.reset(new CdmSession(NULL, kTestOrigin, NULL, NULL));
// Inject testing mocks. // Inject testing mocks.
license_parser_ = new MockCdmLicense(); license_parser_ = new MockCdmLicense();
cdm_session_->set_license_parser(license_parser_); cdm_session_->set_license_parser(license_parser_);

View File

@@ -2118,26 +2118,15 @@ TEST_F(DeviceFilesTest, DeleteLicense) {
EXPECT_FALSE(device_files.LicenseExists(license_test_data[0].key_set_id)); EXPECT_FALSE(device_files.LicenseExists(license_test_data[0].key_set_id));
} }
TEST_F(DeviceFilesTest, ReserveLicenseIds) { TEST_F(DeviceFilesTest, ReserveLicenseIdsDoesNotUseFileSystem) {
// Validate that ReserveLicenseIds does not touch the file system.
MockFile file; MockFile file;
EXPECT_CALL(file, IsDirectory(StrEq(device_base_path_))) EXPECT_CALL(file, IsDirectory(StrEq(device_base_path_))).Times(0);
.Times(kNumberOfLicenses)
.WillRepeatedly(Return(true));
EXPECT_CALL(file, CreateDirectory(_)).Times(0); EXPECT_CALL(file, CreateDirectory(_)).Times(0);
for (size_t i = 0; i < kNumberOfLicenses; ++i) { EXPECT_CALL(file, Open(_, _)).Times(0);
std::string license_path = device_base_path_ + EXPECT_CALL(file, Write(_, _)).Times(0);
license_test_data[i].key_set_id + EXPECT_CALL(file, Close()).Times(0);
DeviceFiles::GetLicenseFileNameExtension();
InSequence calls;
EXPECT_CALL(file, Open(StrEq(license_path),
AllOf(IsCreateFileFlagSet(), IsBinaryFileFlagSet())))
.WillOnce(Return(true));
EXPECT_CALL(file, Write(StrEq(DeviceFiles::GetBlankFileData()),
DeviceFiles::GetBlankFileData().size()))
.WillOnce(ReturnArg<1>());
EXPECT_CALL(file, Close());
}
EXPECT_CALL(file, Read(_, _)).Times(0); EXPECT_CALL(file, Read(_, _)).Times(0);
DeviceFiles device_files; DeviceFiles device_files;
@@ -2145,6 +2134,8 @@ TEST_F(DeviceFilesTest, ReserveLicenseIds) {
device_files.SetTestFile(&file); device_files.SetTestFile(&file);
for (size_t i = 0; i < kNumberOfLicenses; i++) { for (size_t i = 0; i < kNumberOfLicenses; i++) {
EXPECT_TRUE(device_files.ReserveLicenseId(license_test_data[i].key_set_id)); EXPECT_TRUE(device_files.ReserveLicenseId(license_test_data[i].key_set_id));
// Validate that the license IDs are actually reserved.
EXPECT_TRUE(device_files.LicenseExists(license_test_data[i].key_set_id));
} }
} }

View File

@@ -1,6 +1,7 @@
// Copyright 2013 Google Inc. All Rights Reserved. // Copyright 2013 Google Inc. All Rights Reserved.
#include "properties.h" #include "properties.h"
#include "properties_configuration.h"
#include <unistd.h> #include <unistd.h>
#include <sstream> #include <sstream>
@@ -42,6 +43,17 @@ bool GetAndroidProperty(const char* key, std::string* value) {
namespace wvcdm { namespace wvcdm {
void Properties::Init() {
oem_crypto_use_secure_buffers_ = kPropertyOemCryptoUseSecureBuffers;
oem_crypto_use_fifo_ = kPropertyOemCryptoUseFifo;
oem_crypto_use_userspace_buffers_ = kPropertyOemCryptoUseUserSpaceBuffers;
use_certificates_as_identification_ =
kPropertyUseCertificatesAsIdentification;
security_level_path_backward_compatibility_support_ =
kSecurityLevelPathBackwardCompatibilitySupport;
session_property_set_.reset(new CdmClientPropertySetMap());
}
bool Properties::GetCompanyName(std::string* company_name) { bool Properties::GetCompanyName(std::string* company_name) {
if (!company_name) { if (!company_name) {
LOGW("Properties::GetCompanyName: Invalid parameter"); LOGW("Properties::GetCompanyName: Invalid parameter");
@@ -139,4 +151,8 @@ bool Properties::GetOEMCryptoPath(std::string* library_name) {
return true; return true;
} }
bool Properties::AlwaysUseKeySetIds() {
return false;
}
} // namespace wvcdm } // namespace wvcdm