[ Merge of http://go/wvgerrit/154575 ] [ Cherry-pick of http://ag/19498242 ] There is a rare race condition experienced by some Android devices where the a new client property set is being added while another is being removed. The C++ stl library does not provided thread protection by default. This CL adds a new mutex for the client property set map which prevents multiple threads accessing the property sets concurrently. Bug: 235238226 Test: GtsMediaTestCases on redfin Change-Id: I32cf11bfb1332295ba1245071102ff0adc35259d (cherry picked from commitaaa97a5d60) (cherry picked from commit6109ec6d66)
128 lines
4.0 KiB
C++
128 lines
4.0 KiB
C++
// Copyright 2018 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine License
|
|
// Agreement.
|
|
|
|
#include "properties.h"
|
|
|
|
#include "log.h"
|
|
#include "wv_cdm_constants.h"
|
|
|
|
namespace {
|
|
const char* kSecurityLevelDirs[] = {"L1/", "L3/"};
|
|
} // namespace
|
|
|
|
namespace wvcdm {
|
|
using UniqueLock = std::unique_lock<std::mutex>;
|
|
|
|
std::mutex Properties::init_mutex_;
|
|
std::mutex Properties::session_mutex_;
|
|
bool Properties::is_initialized_ = false;
|
|
bool Properties::oem_crypto_use_secure_buffers_;
|
|
bool Properties::oem_crypto_use_fifo_;
|
|
bool Properties::oem_crypto_use_userspace_buffers_;
|
|
bool Properties::provisioning_messages_are_binary_;
|
|
bool Properties::allow_service_certificate_requests_;
|
|
bool Properties::device_files_is_a_real_filesystem_;
|
|
bool Properties::allow_restore_of_offline_licenses_with_release_;
|
|
bool Properties::delay_oem_crypto_termination_;
|
|
std::unique_ptr<CdmClientPropertySetMap> Properties::session_property_set_;
|
|
|
|
bool Properties::AddSessionPropertySet(const CdmSessionId& session_id,
|
|
CdmClientPropertySet* property_set) {
|
|
UniqueLock lock(session_mutex_);
|
|
if (!session_property_set_) {
|
|
return false;
|
|
}
|
|
std::pair<CdmClientPropertySetMap::iterator, bool> result =
|
|
session_property_set_->insert(
|
|
std::pair<const CdmSessionId, CdmClientPropertySet*>(session_id,
|
|
property_set));
|
|
return result.second;
|
|
}
|
|
|
|
bool Properties::RemoveSessionPropertySet(const CdmSessionId& session_id) {
|
|
UniqueLock lock(session_mutex_);
|
|
if (!session_property_set_) {
|
|
return false;
|
|
}
|
|
return (1 == session_property_set_->erase(session_id));
|
|
}
|
|
|
|
CdmClientPropertySet* Properties::GetCdmClientPropertySet(
|
|
const CdmSessionId& session_id) {
|
|
// Call must obtain |session_mutex_|.
|
|
if (session_property_set_) {
|
|
CdmClientPropertySetMap::iterator it =
|
|
session_property_set_->find(session_id);
|
|
if (it != session_property_set_->end()) {
|
|
return it->second;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool Properties::GetApplicationId(const CdmSessionId& session_id,
|
|
std::string* app_id) {
|
|
UniqueLock lock(session_mutex_);
|
|
const CdmClientPropertySet* property_set =
|
|
GetCdmClientPropertySet(session_id);
|
|
if (property_set == nullptr) {
|
|
return false;
|
|
}
|
|
*app_id = property_set->app_id();
|
|
return true;
|
|
}
|
|
|
|
bool Properties::GetServiceCertificate(const CdmSessionId& session_id,
|
|
std::string* service_certificate) {
|
|
UniqueLock lock(session_mutex_);
|
|
const CdmClientPropertySet* property_set =
|
|
GetCdmClientPropertySet(session_id);
|
|
if (property_set == nullptr) {
|
|
return false;
|
|
}
|
|
*service_certificate = property_set->service_certificate();
|
|
return true;
|
|
}
|
|
|
|
bool Properties::SetServiceCertificate(const CdmSessionId& session_id,
|
|
const std::string& service_certificate) {
|
|
UniqueLock lock(session_mutex_);
|
|
CdmClientPropertySet* property_set = GetCdmClientPropertySet(session_id);
|
|
if (property_set == nullptr) {
|
|
return false;
|
|
}
|
|
property_set->set_service_certificate(service_certificate);
|
|
return true;
|
|
}
|
|
|
|
bool Properties::UsePrivacyMode(const CdmSessionId& session_id) {
|
|
UniqueLock lock(session_mutex_);
|
|
const CdmClientPropertySet* property_set =
|
|
GetCdmClientPropertySet(session_id);
|
|
if (property_set == nullptr) {
|
|
return false;
|
|
}
|
|
return property_set->use_privacy_mode();
|
|
}
|
|
|
|
uint32_t Properties::GetSessionSharingId(const CdmSessionId& session_id) {
|
|
UniqueLock lock(session_mutex_);
|
|
const CdmClientPropertySet* property_set =
|
|
GetCdmClientPropertySet(session_id);
|
|
if (property_set == nullptr) {
|
|
return 0;
|
|
}
|
|
return property_set->session_sharing_id();
|
|
}
|
|
|
|
bool Properties::GetSecurityLevelDirectories(std::vector<std::string>* dirs) {
|
|
dirs->resize(sizeof(kSecurityLevelDirs) / sizeof(const char*));
|
|
for (size_t i = 0; i < dirs->size(); ++i) {
|
|
(*dirs)[i] = kSecurityLevelDirs[i];
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace wvcdm
|