Files
android/libwvdrmengine/cdm/core/src/properties.cpp
Alex Dale 381f879ff7 Added mutex protection for session_property_set_.
[ 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 commit aaa97a5d60)
(cherry picked from commit 6109ec6d66)
2022-08-10 21:34:32 +00:00

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