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:
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
AV1A.250627.002
|
AV1A.250714.001
|
||||||
|
|||||||
Reference in New Issue
Block a user