Make change and version bump to AV1A.250714.001

Snap for 13778804 from 919bc45396 to vic-widevine-partner-release

Change-Id: I9a7f2dc82d18ccf5daf118850b8c9f0117bf0967
This commit is contained in:
Android Build Coastguard Worker
2025-07-14 16:22:07 -07:00
9 changed files with 102 additions and 29 deletions

View File

@@ -299,11 +299,29 @@ class WvContentDecryptionModule : public android::RefBase, public TimerHandler {
const std::string& signature); const std::string& signature);
private: private:
struct CdmInfo { class CdmInfo {
CdmInfo(); public:
// This should never be used.
CdmInfo() = delete;
// It is expected that the filesystem loaded into |cdm_engine|
// is the same instance as |file_system|.
CdmInfo(std::unique_ptr<wvutil::FileSystem>&& file_system,
std::unique_ptr<CdmEngine>&& cdm_engine);
// No copy operators.
CdmInfo(const CdmInfo&) = delete;
CdmInfo& operator=(const CdmInfo&) = delete;
// Move operators OK.
CdmInfo(CdmInfo&&) = default;
CdmInfo& operator==(CdmInfo&& other);
wvutil::FileSystem file_system; wvutil::FileSystem* file_system() { return file_system_.get(); }
std::unique_ptr<CdmEngine> cdm_engine; CdmEngine* cdm_engine() { return cdm_engine_.get(); }
private:
// Order matters, |cdm_engine_| is expected to contain a pointer
// to |file_system_|.
std::unique_ptr<wvutil::FileSystem> file_system_;
std::unique_ptr<CdmEngine> cdm_engine_;
}; };
// Finds the CdmEngine instance for the given identifier, creating one if // Finds the CdmEngine instance for the given identifier, creating one if

View File

@@ -566,7 +566,7 @@ CdmResponseType WvContentDecryptionModule::GetCurrentMetricsInternal(
// TODO(blueeyes): Add a better error. // TODO(blueeyes): Add a better error.
return CdmResponseType(UNKNOWN_ERROR); return CdmResponseType(UNKNOWN_ERROR);
} }
return it->second.cdm_engine->GetMetricsSnapshot(metrics) return it->second.cdm_engine()->GetMetricsSnapshot(metrics)
? CdmResponseType(NO_ERROR) ? CdmResponseType(NO_ERROR)
: CdmResponseType(UNKNOWN_ERROR); : CdmResponseType(UNKNOWN_ERROR);
} }
@@ -582,31 +582,52 @@ void WvContentDecryptionModule::SaveMetrics(
WvMetricsSnapshot::MakeSnapshot(identifier, std::move(metrics))); WvMetricsSnapshot::MakeSnapshot(identifier, std::move(metrics)));
} }
WvContentDecryptionModule::CdmInfo::CdmInfo() WvContentDecryptionModule::CdmInfo::CdmInfo(
: cdm_engine(CdmEngineFactory::CreateCdmEngine(&file_system)) {} std::unique_ptr<wvutil::FileSystem>&& file_system,
std::unique_ptr<CdmEngine>&& cdm_engine)
: file_system_(std::move(file_system)),
cdm_engine_(std::move(cdm_engine)) {}
WvContentDecryptionModule::CdmInfo&
WvContentDecryptionModule::CdmInfo::operator==(
WvContentDecryptionModule::CdmInfo&& other) {
// Must move |cdm_engine_| first; the current value depends
// on the current value of |file_system_|.
cdm_engine_ = std::move(other.cdm_engine_);
file_system_ = std::move(other.file_system_);
return *this;
}
CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier( CdmEngine* WvContentDecryptionModule::EnsureCdmForIdentifier(
const CdmIdentifier& identifier) { const CdmIdentifier& identifier) {
CdmEngine* cdm_engine; CdmEngine* cdm_engine = nullptr;
bool enable_timer = false; bool enable_timer = false;
{ {
std::unique_lock<std::mutex> auto_lock(cdms_lock_); std::unique_lock<std::mutex> auto_lock(cdms_lock_);
if (cdms_.size() == 0) enable_timer = true; if (cdms_.empty()) enable_timer = true;
if (cdms_.find(identifier) == cdms_.end()) { auto it = cdms_.find(identifier);
// Accessing the map entry will create a new instance using the default if (it != cdms_.end()) {
// constructor. We then need to provide it with two pieces of info: The // Already exists.
cdm_engine = it->second.cdm_engine();
} else {
std::unique_ptr<wvutil::FileSystem> fs =
std::make_unique<wvutil::FileSystem>();
// Provide it with two pieces of info: The
// origin provided by the app and an identifier that uniquely identifies // origin provided by the app and an identifier that uniquely identifies
// this CDM. We concatenate all pieces of the CdmIdentifier in order to // this CDM. We concatenate all pieces of the CdmIdentifier in order to
// create an ID that is unique to that identifier. // create an ID that is unique to that identifier.
cdms_[identifier].file_system.set_origin(identifier.origin); fs->set_origin(identifier.origin);
cdms_[identifier].file_system.set_identifier(identifier.spoid + fs->set_identifier(identifier.spoid + identifier.origin);
identifier.origin);
cdms_[identifier].cdm_engine->SetAppPackageName( std::unique_ptr<CdmEngine> engine(
identifier.app_package_name); CdmEngineFactory::CreateCdmEngine(fs.get()));
cdms_[identifier].cdm_engine->SetSpoid(identifier.spoid); engine->SetAppPackageName(identifier.app_package_name);
cdms_[identifier].cdm_engine->SetUserId(identifier.user_id); engine->SetSpoid(identifier.spoid);
engine->SetUserId(identifier.user_id);
cdm_engine = engine.get();
cdms_.emplace(identifier, CdmInfo(std::move(fs), std::move(engine)));
} }
cdm_engine = cdms_[identifier].cdm_engine.get();
} }
// Do not enable timer while holding on to the |cdms_lock_| // Do not enable timer while holding on to the |cdms_lock_|
if (enable_timer) EnableTimer(); if (enable_timer) EnableTimer();
@@ -649,7 +670,7 @@ CdmResponseType WvContentDecryptionModule::CloseCdm(
// TODO(blueeyes): Create a better error. // TODO(blueeyes): Create a better error.
return CdmResponseType(UNKNOWN_ERROR); return CdmResponseType(UNKNOWN_ERROR);
} }
CdmEngine* cdm_engine = cdm_it->second.cdm_engine.get(); CdmEngine* cdm_engine = cdm_it->second.cdm_engine();
// Save metrics snapshot. // Save metrics snapshot.
drm_metrics::WvCdmMetrics metrics; drm_metrics::WvCdmMetrics metrics;
const bool success = cdm_engine->GetMetricsSnapshot(&metrics); const bool success = cdm_engine->GetMetricsSnapshot(&metrics);
@@ -738,7 +759,7 @@ void WvContentDecryptionModule::OnTimerEvent() {
std::unique_lock<std::mutex> auto_lock(cdms_lock_); std::unique_lock<std::mutex> auto_lock(cdms_lock_);
for (auto it = cdms_.begin(); it != cdms_.end(); ++it) { for (auto it = cdms_.begin(); it != cdms_.end(); ++it) {
LoggingUidSetter set_uid(it->first.user_id); LoggingUidSetter set_uid(it->first.user_id);
it->second.cdm_engine->OnTimerEvent(); it->second.cdm_engine()->OnTimerEvent();
} }
if (cdms_.empty()) { if (cdms_.empty()) {
// The following code cannot be attributed to any app uid. // The following code cannot be attributed to any app uid.

View File

@@ -26,9 +26,9 @@ struct CoreMessageFeatures {
// This is the published version of the ODK Core Message library. The default // This is the published version of the ODK Core Message library. The default
// behavior is for the server to restrict messages to at most this version // behavior is for the server to restrict messages to at most this version
// number. The default is 19.1. // number. The default is 19.2.
uint32_t maximum_major_version = 19; uint32_t maximum_major_version = 19;
uint32_t maximum_minor_version = 1; uint32_t maximum_minor_version = 2;
bool operator==(const CoreMessageFeatures &other) const; bool operator==(const CoreMessageFeatures &other) const;
bool operator!=(const CoreMessageFeatures &other) const { bool operator!=(const CoreMessageFeatures &other) const {

View File

@@ -16,7 +16,7 @@ extern "C" {
/* The version of this library. */ /* The version of this library. */
#define ODK_MAJOR_VERSION 19 #define ODK_MAJOR_VERSION 19
#define ODK_MINOR_VERSION 1 #define ODK_MINOR_VERSION 2
/* ODK Version string. Date changed automatically on each release. */ /* ODK Version string. Date changed automatically on each release. */
#define ODK_RELEASE_DATE "ODK v19.1 2024-03-25" #define ODK_RELEASE_DATE "ODK v19.1 2024-03-25"

View File

@@ -33,7 +33,7 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures(
features.maximum_minor_version = 4; // 18.4 features.maximum_minor_version = 4; // 18.4
break; break;
case 19: case 19:
features.maximum_minor_version = 1; // 19.1 features.maximum_minor_version = 2; // 19.2
break; break;
default: default:
features.maximum_minor_version = 0; features.maximum_minor_version = 0;

View File

@@ -8,6 +8,8 @@
#include "odk_serialize.h" #include "odk_serialize.h"
#include "odk_message.h"
#include "odk_overflow.h"
#include "odk_structs_priv.h" #include "odk_structs_priv.h"
#include "serialization_base.h" #include "serialization_base.h"
@@ -237,6 +239,36 @@ static void Unpack_OEMCrypto_KeyObject(ODK_Message* msg,
Unpack_OEMCrypto_Substring(msg, &obj->key_data); Unpack_OEMCrypto_Substring(msg, &obj->key_data);
Unpack_OEMCrypto_Substring(msg, &obj->key_control_iv); Unpack_OEMCrypto_Substring(msg, &obj->key_control_iv);
Unpack_OEMCrypto_Substring(msg, &obj->key_control); Unpack_OEMCrypto_Substring(msg, &obj->key_control);
/*
Edge case for servers that incorrectly process protocol VERSION_2_2 padding.
Key data in proto is present, but each key's position in the core
message is missing.
Use the key_data_iv offset to determine if the key_data is present.
This assumes that the serialized protobuf is deterministically ordered, and
that the content key is always 16 bytes. These assumptions should hold true
for v16 and older servers.
*/
if (ODK_Message_GetStatus(msg) == MESSAGE_STATUS_OK &&
obj->key_data.offset == 0 && obj->key_data.length == 0) {
const size_t kKeyDataProtoHeaderSize = 2;
obj->key_data.offset = obj->key_data_iv.offset + obj->key_data_iv.length +
kKeyDataProtoHeaderSize;
obj->key_data.length = 16u; // assume 16-byte key
// Check for overflow. The offset is relative to the end of the core
// message, so add that length to the calculation.
size_t substring_end = 0; // offset + length
size_t end = 0; // offset + length + message_length
if (odk_add_overflow_ux(obj->key_data.offset, obj->key_data.length,
&substring_end) ||
odk_add_overflow_ux(substring_end, ODK_Message_GetSize(msg), &end) ||
end > ODK_Message_GetCapacity(msg)) {
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
return;
}
}
} }
static void Unpack_ODK_TimerLimits(ODK_Message* msg, ODK_TimerLimits* obj) { static void Unpack_ODK_TimerLimits(ODK_Message* msg, ODK_TimerLimits* obj) {

View File

@@ -277,7 +277,7 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
nonce_values->api_minor_version = 4; nonce_values->api_minor_version = 4;
break; break;
case 19: case 19:
nonce_values->api_minor_version = 1; nonce_values->api_minor_version = 2;
break; break;
default: default:
nonce_values->api_minor_version = 0; nonce_values->api_minor_version = 0;

View File

@@ -1275,7 +1275,7 @@ std::vector<VersionParameters> TestCases() {
{16, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 16, 5}, {16, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 16, 5},
{17, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 17, 2}, {17, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 17, 2},
{18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 4}, {18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 4},
{19, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 19, 1}, {19, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 19, 2},
// Here are some known good versions. Make extra sure they work. // Here are some known good versions. Make extra sure they work.
{ODK_MAJOR_VERSION, 16, 3, 16, 3}, {ODK_MAJOR_VERSION, 16, 3, 16, 3},
{ODK_MAJOR_VERSION, 16, 4, 16, 4}, {ODK_MAJOR_VERSION, 16, 4, 16, 4},
@@ -1288,6 +1288,7 @@ std::vector<VersionParameters> TestCases() {
{ODK_MAJOR_VERSION, 18, 4, 18, 4}, {ODK_MAJOR_VERSION, 18, 4, 18, 4},
{ODK_MAJOR_VERSION, 19, 0, 19, 0}, {ODK_MAJOR_VERSION, 19, 0, 19, 0},
{ODK_MAJOR_VERSION, 19, 1, 19, 1}, {ODK_MAJOR_VERSION, 19, 1, 19, 1},
{ODK_MAJOR_VERSION, 19, 2, 19, 2},
{0, 16, 3, 16, 3}, {0, 16, 3, 16, 3},
{0, 16, 4, 16, 4}, {0, 16, 4, 16, 4},
{0, 16, 5, 16, 5}, {0, 16, 5, 16, 5},
@@ -1297,6 +1298,7 @@ std::vector<VersionParameters> TestCases() {
{0, 18, 4, 18, 4}, {0, 18, 4, 18, 4},
{0, 19, 0, 19, 0}, {0, 19, 0, 19, 0},
{0, 19, 1, 19, 1}, {0, 19, 1, 19, 1},
{0, 19, 2, 19, 2},
}; };
return test_cases; return test_cases;
} }

View File

@@ -1 +1 @@
AV1A.250627.002 AV1A.250714.001