Snap for 7519874 from b6cdd12394 to sc-release
Change-Id: Ib05998ed7e4d75d856bd331d9497bd4270066fbe
This commit is contained in:
@@ -96,7 +96,8 @@ const char kUsageInfoFileNameExt[] = ".bin";
|
||||
const char kUsageInfoFileNamePrefix[] = "usage";
|
||||
const char kUsageTableFileName[] = "usgtable.bin";
|
||||
const char kWildcard[] = "*";
|
||||
constexpr int64_t kFourMonthsInSeconds = (2 * 30 + 2 * 31) * 24 * 60 * 60;
|
||||
// TODO(b/192430982): Renable expiration of legacy DRM certificates
|
||||
// constexpr int64_t kFourMonthsInSeconds = (2 * 30 + 2 * 31) * 24 * 60 * 60;
|
||||
|
||||
// Helper methods
|
||||
bool SetDeviceCertificate(const std::string& certificate,
|
||||
@@ -427,7 +428,9 @@ bool DeviceFiles::StoreCertificate(const std::string& certificate,
|
||||
if (default_certificate) {
|
||||
Clock clock;
|
||||
device_certificate->set_acquisition_time_seconds(clock.GetCurrentTime());
|
||||
} else {
|
||||
}
|
||||
/* TODO(b/192430982): Renable expiration of legacy DRM certificates
|
||||
else {
|
||||
// Since certificates of type kCertificateAtsc are not allowed to be
|
||||
// stored, this is a certificate of type kCertificateLegacy.
|
||||
// The only time when a legacy certificate is stored is when it does not
|
||||
@@ -440,6 +443,7 @@ bool DeviceFiles::StoreCertificate(const std::string& certificate,
|
||||
current_time + kFourMonthsInSeconds +
|
||||
rng.RandomInRange(kFourMonthsInSeconds));
|
||||
}
|
||||
*/
|
||||
|
||||
std::string serialized_file;
|
||||
file.SerializeToString(&serialized_file);
|
||||
@@ -595,6 +599,7 @@ DeviceFiles::CertificateState DeviceFiles::RetrieveCertificate(
|
||||
}
|
||||
|
||||
case kCertificateLegacy: {
|
||||
/* TODO(b/192430982): Renable expiration of legacy DRM certificates
|
||||
// Validation check for DRM certificate without an expiration
|
||||
// time set by the provisioning service. Add an expiry time
|
||||
// within the next 6 months +/- 2 months, if one has not been set.
|
||||
@@ -611,6 +616,7 @@ DeviceFiles::CertificateState DeviceFiles::RetrieveCertificate(
|
||||
}
|
||||
|
||||
if (current_time > expiration_time_seconds) return kCertificateExpired;
|
||||
*/
|
||||
|
||||
return kCertificateValid;
|
||||
}
|
||||
|
||||
@@ -1568,8 +1568,10 @@ const CertificateErrorData kRetrieveLegacyCertificateErrorData[] = {
|
||||
kTestLegacyCertificateFileDataInvalidClientExpiration},
|
||||
};
|
||||
|
||||
/* TODO(b/192430982): Renable expiration of legacy DRM certificates
|
||||
constexpr size_t kNumberOfLegacyCertificates =
|
||||
ArraySize(kRetrieveLegacyCertificateErrorData);
|
||||
*/
|
||||
|
||||
const CertificateErrorData kRetrieveDefaultCertificateErrorData[] = {
|
||||
// Certificate expired
|
||||
@@ -4020,6 +4022,7 @@ TEST_F(DeviceFilesTest, RetrieveAtscCertificateNotFound) {
|
||||
&serial_number, &system_id));
|
||||
}
|
||||
|
||||
/* TODO(b/192430982): Renable expiration of legacy DRM certificates
|
||||
TEST_F(DeviceFilesTest, RetrieveLegacyCertificateWithoutExpirationTime) {
|
||||
MockFileSystem file_system;
|
||||
std::string certificate_file_name;
|
||||
@@ -4221,6 +4224,7 @@ TEST_F(DeviceFilesTest, RetrieveDefaultCertificate) {
|
||||
EXPECT_EQ(kTestWrappedKey, private_key);
|
||||
EXPECT_EQ("7CB49F987A635E1E0A52184694582D6E", b2a_hex(serial_number));
|
||||
}
|
||||
*/
|
||||
|
||||
TEST_F(DeviceFilesTest, RetrieveDefaultCertificateNeverExpires) {
|
||||
MockFileSystem file_system;
|
||||
@@ -4331,7 +4335,9 @@ TEST_F(DeviceFilesTest, RetrieveCertificateWithoutKeyType) {
|
||||
// Call to Open will return a unique_ptr, freeing this object.
|
||||
// The file will be re-written with a new client expiration time
|
||||
MockFile* read_file = new MockFile();
|
||||
/* TODO(b/192430982): Renable expiration of legacy DRM certificates
|
||||
MockFile* write_file = new MockFile();
|
||||
*/
|
||||
EXPECT_CALL(file_system, Exists(StrEq(device_legacy_certificate_path)))
|
||||
.Times(AtLeast(1))
|
||||
.WillRepeatedly(Return(true));
|
||||
@@ -4341,17 +4347,21 @@ TEST_F(DeviceFilesTest, RetrieveCertificateWithoutKeyType) {
|
||||
EXPECT_CALL(file_system, FileSize(StrEq(device_legacy_certificate_path)))
|
||||
.WillOnce(Return(data.size()));
|
||||
EXPECT_CALL(file_system, DoOpen(StrEq(device_legacy_certificate_path), _))
|
||||
.WillOnce(Return(read_file))
|
||||
.WillOnce(Return(write_file));
|
||||
.WillOnce(Return(read_file));
|
||||
/* TODO(b/192430982): Renable expiration of legacy DRM certificates
|
||||
.WillOnce(Return(write_file));
|
||||
*/
|
||||
EXPECT_CALL(*read_file, Read(NotNull(), Eq(data.size())))
|
||||
.WillOnce(DoAll(SetArrayArgument<0>(data.begin(), data.end()),
|
||||
Return(data.size())));
|
||||
EXPECT_CALL(*read_file, Write(_, _)).Times(0);
|
||||
/* TODO(b/192430982): Renable expiration of legacy DRM certificates
|
||||
EXPECT_CALL(*write_file, Read(_, _)).Times(0);
|
||||
EXPECT_CALL(*write_file, Write(_, _))
|
||||
.With(AllArgs(StrAndLenContains(std::vector<std::string>{
|
||||
kTestCertificateWithoutExpiration, kTestWrappedKey.key()})))
|
||||
.WillOnce(ReturnArg<1>());
|
||||
*/
|
||||
|
||||
DeviceFiles device_files(&file_system);
|
||||
EXPECT_TRUE(device_files.Init(kSecurityLevelL1));
|
||||
|
||||
@@ -215,6 +215,14 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
|
||||
void DisableTimerAndWaitForExit();
|
||||
void OnTimerEvent();
|
||||
|
||||
// Fill the |metrics| parameter with the metrics data for the CdmEngine
|
||||
// associated with the given |identifier|. If the CdmEngine instance does
|
||||
// not exist, this will return an error.
|
||||
// This methods assumes that |metrics| is not null and that the |cdms_lock_|
|
||||
// has already been acquired.
|
||||
CdmResponseType GetMetricsInternal(const CdmIdentifier& identifier,
|
||||
drm_metrics::WvCdmMetrics* metrics);
|
||||
|
||||
static std::mutex session_sharing_id_generation_lock_;
|
||||
std::mutex timer_lock_;
|
||||
Timer timer_;
|
||||
@@ -222,14 +230,27 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
|
||||
// instance variables
|
||||
// This manages the lifetime of the CDM instances.
|
||||
std::map<CdmIdentifier, CdmInfo> cdms_;
|
||||
std::mutex cdms_lock_;
|
||||
|
||||
// This contains weak pointers to the CDM instances contained in |cdms_|.
|
||||
std::map<std::string, CdmEngine*> cdm_by_session_id_;
|
||||
// Lock for accessing either |cdms_| or |cdm_by_session_id_|.
|
||||
// This lock should be acquired for any of the following:
|
||||
// 1) Getting a CDM instance from |cdms_| or |cdm_by_session_id_|
|
||||
// - Hold lock while searching, release lock once pointer is acquired
|
||||
// 2) Iterating over |cdms_| or |cdm_by_session_id_|
|
||||
// - Hold lock for the entire duration of iterating over CDMs
|
||||
// - DO NOT release the lock until all operations are complete
|
||||
// - This MUST be done regardless of whether |cdms_| or
|
||||
// |cdm_by_session_id_| is being modified
|
||||
// 3) Creating a new CDM instance with |cdms_|
|
||||
// - Hold lock when creating AND initializing the CDM
|
||||
// - Release once CDM is fully initialized
|
||||
// 4) Linking a session to a CDM with |cdm_by_session_id_|
|
||||
// - Hold lock when mapping a session ID to a CDM, release once set
|
||||
// 5) Unlinking a session from a CDM with |cdm_by_session_id_|
|
||||
// - Hold lock when erasing, release once erased.
|
||||
std::mutex cdms_lock_;
|
||||
|
||||
CORE_DISALLOW_COPY_AND_ASSIGN(WvContentDecryptionModule);
|
||||
};
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // CDM_BASE_WV_CONTENT_DECRYPTION_MODULE_H_
|
||||
|
||||
@@ -71,6 +71,7 @@ CdmResponseType WvContentDecryptionModule::OpenSession(
|
||||
CdmResponseType sts = cdm_engine->OpenSession(key_system, property_set,
|
||||
event_listener, session_id);
|
||||
if (sts == NO_ERROR) {
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
cdm_by_session_id_[*session_id] = cdm_engine;
|
||||
}
|
||||
return sts;
|
||||
@@ -82,12 +83,11 @@ CdmResponseType WvContentDecryptionModule::CloseSession(
|
||||
CdmEngine* cdm_engine = GetCdmForSessionId(session_id);
|
||||
// TODO(rfrias): Avoid reusing the error codes from CdmEngine.
|
||||
if (!cdm_engine) return SESSION_NOT_FOUND_1;
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
CdmResponseType sts = cdm_engine->CloseSession(session_id);
|
||||
const CdmResponseType sts = cdm_engine->CloseSession(session_id);
|
||||
if (sts == NO_ERROR) {
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
cdm_by_session_id_.erase(session_id);
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
|
||||
if (license_type == kLicenseTypeRelease) {
|
||||
sts = cdm_engine->OpenKeySetSession(key_set_id, property_set, nullptr);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
cdm_by_session_id_[key_set_id] = cdm_engine;
|
||||
}
|
||||
|
||||
@@ -130,6 +131,7 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
|
||||
app_parameters, key_request);
|
||||
if (license_type == kLicenseTypeRelease && sts != KEY_MESSAGE) {
|
||||
cdm_engine->CloseKeySetSession(key_set_id);
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
cdm_by_session_id_.erase(key_set_id);
|
||||
}
|
||||
return sts;
|
||||
@@ -152,6 +154,7 @@ CdmResponseType WvContentDecryptionModule::AddKey(
|
||||
// Empty session id indicates license type release.
|
||||
if (sts == KEY_ADDED && session_id.empty()) {
|
||||
cdm_engine->CloseKeySetSession(release_key_set_id);
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
cdm_by_session_id_.erase(release_key_set_id);
|
||||
}
|
||||
return sts;
|
||||
@@ -297,11 +300,11 @@ CdmResponseType WvContentDecryptionModule::GetSecureStopIds(
|
||||
}
|
||||
|
||||
CdmEngine* cdm_engine = EnsureCdmForIdentifier(identifier);
|
||||
CdmResponseType sts =
|
||||
const CdmResponseType sts =
|
||||
cdm_engine->ListUsageIds(app_id, kSecurityLevelL1, nullptr, ssids);
|
||||
std::vector<CdmSecureStopId> secure_stop_ids;
|
||||
CdmResponseType sts_l3 = cdm_engine->ListUsageIds(app_id, kSecurityLevelL3,
|
||||
nullptr, &secure_stop_ids);
|
||||
const CdmResponseType sts_l3 = cdm_engine->ListUsageIds(
|
||||
app_id, kSecurityLevelL3, nullptr, &secure_stop_ids);
|
||||
ssids->insert(ssids->end(), secure_stop_ids.begin(), secure_stop_ids.end());
|
||||
return sts_l3 != NO_ERROR ? sts_l3 : sts;
|
||||
}
|
||||
@@ -383,17 +386,19 @@ CdmResponseType WvContentDecryptionModule::GetMetrics(
|
||||
if (!metrics || !full_list_returned) {
|
||||
return PARAMETER_NULL;
|
||||
}
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
for (auto& key_value_pair : cdms_) {
|
||||
const CdmIdentifier& identifier = key_value_pair.first;
|
||||
drm_metrics::WvCdmMetrics metric;
|
||||
CdmResponseType status = GetMetrics(key_value_pair.first, &metric);
|
||||
const CdmResponseType status = GetMetricsInternal(identifier, &metric);
|
||||
if (status == NO_ERROR) {
|
||||
metrics->push_back(metric);
|
||||
} else {
|
||||
LOGD("GetMetrics call failed: cdm identifier=%u, error=%d",
|
||||
key_value_pair.first.unique_id, status);
|
||||
identifier.unique_id, status);
|
||||
}
|
||||
}
|
||||
// With no streaming activities, cdms_ size would be zero,
|
||||
// With no streaming activities, |cdms_| size would be zero,
|
||||
// treat it as a non full list in that case.
|
||||
*full_list_returned = !cdms_.empty() && metrics->size() == cdms_.size();
|
||||
|
||||
@@ -410,6 +415,12 @@ CdmResponseType WvContentDecryptionModule::GetMetrics(
|
||||
return PARAMETER_NULL;
|
||||
}
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
return GetMetricsInternal(identifier, metrics);
|
||||
}
|
||||
|
||||
CdmResponseType WvContentDecryptionModule::GetMetricsInternal(
|
||||
const CdmIdentifier& identifier, drm_metrics::WvCdmMetrics* metrics) {
|
||||
// Note: Caller should lock before calling.
|
||||
auto it = cdms_.find(identifier);
|
||||
if (it == cdms_.end()) {
|
||||
LOGE("Cdm Identifier not found");
|
||||
@@ -454,6 +465,7 @@ CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier(
|
||||
|
||||
CdmEngine* WvContentDecryptionModule::GetCdmForSessionId(
|
||||
const std::string& session_id) {
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
// Use find to avoid creating empty entries when not found.
|
||||
auto it = cdm_by_session_id_.find(session_id);
|
||||
if (it == cdm_by_session_id_.end()) return nullptr;
|
||||
@@ -462,10 +474,8 @@ CdmEngine* WvContentDecryptionModule::GetCdmForSessionId(
|
||||
|
||||
void WvContentDecryptionModule::CloseAllCdms() {
|
||||
std::unique_lock<std::mutex> auto_lock(cdms_lock_);
|
||||
|
||||
for (auto it = cdms_.begin(); it != cdms_.end();) {
|
||||
it = cdms_.erase(it);
|
||||
}
|
||||
cdm_by_session_id_.clear();
|
||||
cdms_.clear();
|
||||
}
|
||||
|
||||
CdmResponseType WvContentDecryptionModule::CloseCdm(
|
||||
|
||||
Reference in New Issue
Block a user