Bug 1623661 - Remove the ability to instantiate CDM9. r=alwu

This patch removes the code that tries to instantiate CDM interface version 9.
This code is no longer needed as Widevine have moved away from this interface.
At the time of writing Chromium have not used this interface for more than a
year, and Mozilla have not shipped CDMs using the interface for at least 6
months.

Differential Revision: https://phabricator.services.mozilla.com/D68046

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Bryce Seager van Dyk 2020-03-24 18:39:00 +00:00
parent 98d5951dcc
commit 39709a7876
3 changed files with 40 additions and 248 deletions

View File

@ -51,8 +51,7 @@ void ChromiumCDMAdapter::SetAdaptee(PRLibrary* aLib) { mLib = aLib; }
void* ChromiumCdmHost(int aHostInterfaceVersion, void* aUserData) {
GMP_LOG_DEBUG("ChromiumCdmHostFunc(%d, %p)", aHostInterfaceVersion,
aUserData);
if (aHostInterfaceVersion != cdm::Host_9::kVersion &&
aHostInterfaceVersion != cdm::Host_10::kVersion) {
if (aHostInterfaceVersion != cdm::Host_10::kVersion) {
return nullptr;
}
return aUserData;
@ -104,34 +103,40 @@ GMPErr ChromiumCDMAdapter::GMPGetAPI(const char* aAPIName, void* aHostAPI,
void** aPluginAPI, uint32_t aDecryptorId) {
GMP_LOG_DEBUG("ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p",
aAPIName, aHostAPI, aPluginAPI, aDecryptorId, this);
bool isCDM10 = !strcmp(aAPIName, CHROMIUM_CDM_API);
bool isCDM9 = !strcmp(aAPIName, CHROMIUM_CDM_API_BACKWARD_COMPAT);
if (isCDM9 || isCDM10) {
auto create = reinterpret_cast<decltype(::CreateCdmInstance)*>(
PR_FindFunctionSymbol(mLib, "CreateCdmInstance"));
if (!create) {
GMP_LOG_DEBUG(
"ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p "
"FAILED to find CreateCdmInstance",
aAPIName, aHostAPI, aPluginAPI, aDecryptorId, this);
return GMPGenericErr;
}
bool isCdm10 = !strcmp(aAPIName, CHROMIUM_CDM_API);
int version = isCDM9 ? cdm::ContentDecryptionModule_9::kVersion
: cdm::ContentDecryptionModule_10::kVersion;
void* cdm = create(version, EME_KEY_SYSTEM_WIDEVINE,
mozilla::ArrayLength(EME_KEY_SYSTEM_WIDEVINE) - 1,
&ChromiumCdmHost, aHostAPI);
if (!cdm) {
GMP_LOG_DEBUG(
"ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p "
"FAILED to create cdm version %d",
aAPIName, aHostAPI, aPluginAPI, aDecryptorId, this, version);
return GMPGenericErr;
}
GMP_LOG_DEBUG("cdm: 0x%p, version: %d", cdm, version);
*aPluginAPI = cdm;
if (!isCdm10) {
MOZ_ASSERT_UNREACHABLE("We only support and expect cdm10!");
GMP_LOG_DEBUG(
"ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p got "
"unsupported CDM version!",
aAPIName, aHostAPI, aPluginAPI, aDecryptorId, this);
return GMPGenericErr;
}
auto create = reinterpret_cast<decltype(::CreateCdmInstance)*>(
PR_FindFunctionSymbol(mLib, "CreateCdmInstance"));
if (!create) {
GMP_LOG_DEBUG(
"ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p "
"FAILED to find CreateCdmInstance",
aAPIName, aHostAPI, aPluginAPI, aDecryptorId, this);
return GMPGenericErr;
}
const int version = cdm::ContentDecryptionModule_10::kVersion;
void* cdm = create(version, EME_KEY_SYSTEM_WIDEVINE,
mozilla::ArrayLength(EME_KEY_SYSTEM_WIDEVINE) - 1,
&ChromiumCdmHost, aHostAPI);
if (!cdm) {
GMP_LOG_DEBUG(
"ChromiumCDMAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p "
"FAILED to create cdm version %d",
aAPIName, aHostAPI, aPluginAPI, aDecryptorId, this, version);
return GMPGenericErr;
}
GMP_LOG_DEBUG("cdm: 0x%p, version: %d", cdm, version);
*aPluginAPI = cdm;
return *aPluginAPI ? GMPNoErr : GMPNotImplementedErr;
}
@ -152,10 +157,8 @@ bool ChromiumCDMAdapter::Supports(int32_t aModuleVersion,
int32_t aInterfaceVersion,
int32_t aHostVersion) {
return aModuleVersion == CDM_MODULE_VERSION &&
(aInterfaceVersion == cdm::ContentDecryptionModule_9::kVersion ||
aInterfaceVersion == cdm::ContentDecryptionModule_10::kVersion) &&
(aHostVersion == cdm::Host_9::kVersion ||
aHostVersion == cdm::Host_10::kVersion);
aInterfaceVersion == cdm::ContentDecryptionModule_10::kVersion &&
aHostVersion == cdm::Host_10::kVersion;
}
#ifdef XP_WIN

View File

@ -16,9 +16,7 @@ namespace gmp {
class GMPContentChild;
class ChromiumCDMChild : public PChromiumCDMChild,
public cdm::Host_9,
public cdm::Host_10 {
class ChromiumCDMChild : public PChromiumCDMChild, public cdm::Host_10 {
public:
// Mark AddRef and Release as `final`, as they overload pure virtual
// implementations in PChromiumCDMChild.
@ -30,7 +28,7 @@ class ChromiumCDMChild : public PChromiumCDMChild,
void TimerExpired(void* aContext);
// Shared cdm::Host_9 and cdm::Host10 implementation
// cdm::Host_10 implementation
cdm::Buffer* Allocate(uint32_t aCapacity) override;
void SetTimer(int64_t aDelayMs, void* aContext) override;
cdm::Time GetCurrentWallTime() override;
@ -62,10 +60,8 @@ class ChromiumCDMChild : public PChromiumCDMChild,
cdm::Status aDecoderStatus) override {}
void RequestStorageId(uint32_t aVersion) override;
cdm::FileIO* CreateFileIO(cdm::FileIOClient* aClient) override;
// End shared cdm::Host_9 and cdm::Host10 implementation
// cdm::Host_10 specific
void OnInitialized(bool aSuccess) override;
// end cdm::Host_10 specific
// end cdm::Host_10 specific methods
void GiveBuffer(ipc::Shmem&& aBuffer);

View File

@ -83,205 +83,6 @@ mozilla::ipc::IPCResult GMPContentChild::RecvPGMPVideoEncoderConstructor(
return IPC_OK();
}
// Convert CDM10 calls to CDM9 calls, massage args where needed
class ChromiumCDM9BackwardsCompat : public cdm::ContentDecryptionModule_10 {
public:
explicit ChromiumCDM9BackwardsCompat(cdm::Host_10* aHost,
cdm::ContentDecryptionModule_9* aCDM)
: mCDM(aCDM), mHost(aHost) {}
void Initialize(bool aAllowDistinctiveIdentifier, bool aAllowPersistentState,
bool /* aUseHardwareSecureCodec */) override {
// aUseHardwareSecureCodec is not used by CDM9
mCDM->Initialize(aAllowDistinctiveIdentifier, aAllowPersistentState);
// CDM9 should init synchronously and does not call an OnInit callback, so
// we make sure it's called here.
mHost->OnInitialized(true);
}
void GetStatusForPolicy(uint32_t aPromiseId,
const cdm::Policy& policy) override {
mCDM->GetStatusForPolicy(aPromiseId, policy);
}
void SetServerCertificate(uint32_t aPromiseId,
const uint8_t* aServerCertificateData,
uint32_t aServerCertificateDataSize) override {
mCDM->SetServerCertificate(aPromiseId, aServerCertificateData,
aServerCertificateDataSize);
}
void CreateSessionAndGenerateRequest(uint32_t aPromiseId,
cdm::SessionType aSessionType,
cdm::InitDataType aInitDataType,
const uint8_t* aInitData,
uint32_t aInitDataSize) override {
mCDM->CreateSessionAndGenerateRequest(
aPromiseId, aSessionType, aInitDataType, aInitData, aInitDataSize);
}
void LoadSession(uint32_t aPromiseId, cdm::SessionType aSessionType,
const char* aSessionId, uint32_t aSessionIdSize) override {
mCDM->LoadSession(aPromiseId, aSessionType, aSessionId, aSessionIdSize);
}
void UpdateSession(uint32_t aPromiseId, const char* aSessionId,
uint32_t aSessionIdSize, const uint8_t* aResponse,
uint32_t aResponseSize) override {
mCDM->UpdateSession(aPromiseId, aSessionId, aSessionIdSize, aResponse,
aResponseSize);
}
void CloseSession(uint32_t aPromiseId, const char* aSessionId,
uint32_t aSessionIdSize) override {
mCDM->CloseSession(aPromiseId, aSessionId, aSessionIdSize);
}
void RemoveSession(uint32_t aPromiseId, const char* aSessionId,
uint32_t aSessionIdSize) override {
mCDM->RemoveSession(aPromiseId, aSessionId, aSessionIdSize);
}
void TimerExpired(void* aContext) override { mCDM->TimerExpired(aContext); }
cdm::Status Decrypt(const cdm::InputBuffer_2& aEncryptedBuffer,
cdm::DecryptedBlock* aDecryptedBuffer) override {
// Handle possible encryption mismatch
if (!IsEncryptionSchemeSupported(aEncryptedBuffer.encryption_scheme)) {
return cdm::Status::kDecryptError;
}
return mCDM->Decrypt(ConvertToInputBuffer_1(aEncryptedBuffer),
aDecryptedBuffer);
}
cdm::Status InitializeAudioDecoder(
const cdm::AudioDecoderConfig_2& aAudioDecoderConfig) override {
// Handle possible encryption mismatch
if (!IsEncryptionSchemeSupported(aAudioDecoderConfig.encryption_scheme)) {
return cdm::Status::kInitializationError;
}
return mCDM->InitializeAudioDecoder(
ConverToAudioDecoderConfig_1(aAudioDecoderConfig));
}
cdm::Status InitializeVideoDecoder(
const cdm::VideoDecoderConfig_2& aVideoDecoderConfig) override {
// Handle possible encryption mismatch
if (!IsEncryptionSchemeSupported(aVideoDecoderConfig.encryption_scheme)) {
return cdm::Status::kInitializationError;
}
return mCDM->InitializeVideoDecoder(
ConvertToVideoDecoderConfig_1(aVideoDecoderConfig));
}
void DeinitializeDecoder(cdm::StreamType aDecoderType) override {
mCDM->DeinitializeDecoder(aDecoderType);
}
void ResetDecoder(cdm::StreamType aDecoderType) override {
mCDM->ResetDecoder(aDecoderType);
}
cdm::Status DecryptAndDecodeFrame(const cdm::InputBuffer_2& aEncryptedBuffer,
cdm::VideoFrame* aVideoFrame) override {
// Handle possible encryption mismatch
if (!IsEncryptionSchemeSupported(aEncryptedBuffer.encryption_scheme)) {
return cdm::Status::kDecryptError;
}
return mCDM->DecryptAndDecodeFrame(ConvertToInputBuffer_1(aEncryptedBuffer),
aVideoFrame);
}
cdm::Status DecryptAndDecodeSamples(
const cdm::InputBuffer_2& aEncryptedBuffer,
cdm::AudioFrames* aAudioFrames) override {
// Handle possible encryption mismatch
if (!IsEncryptionSchemeSupported(aEncryptedBuffer.encryption_scheme)) {
return cdm::Status::kDecryptError;
}
return mCDM->DecryptAndDecodeSamples(
ConvertToInputBuffer_1(aEncryptedBuffer), aAudioFrames);
}
void OnPlatformChallengeResponse(
const cdm::PlatformChallengeResponse& aResponse) override {
mCDM->OnPlatformChallengeResponse(aResponse);
}
void OnQueryOutputProtectionStatus(cdm::QueryResult aResult,
uint32_t aLinkMask,
uint32_t aOutputProtectionMask) override {
mCDM->OnQueryOutputProtectionStatus(aResult, aLinkMask,
aOutputProtectionMask);
}
void OnStorageId(uint32_t aVersion, const uint8_t* aStorageId,
uint32_t aStorageIdSize) override {
mCDM->OnStorageId(aVersion, aStorageId, aStorageIdSize);
}
void Destroy() override {
mCDM->Destroy();
delete this;
}
cdm::ContentDecryptionModule_9* mCDM;
cdm::Host_10* mHost;
private:
// CDM9 supports non-encrypted or cenc encrypted media, anything else should
// be rejected.
static bool IsEncryptionSchemeSupported(
const cdm::EncryptionScheme& aEncryptionScheme) {
return aEncryptionScheme == cdm::EncryptionScheme::kUnencrypted ||
aEncryptionScheme == cdm::EncryptionScheme::kCenc;
}
// Conversion functions that drop the encryption scheme member. CDMs prior to
// 10 assumed no encryption or cenc encryption (if encryption is present). So
// we can drop the scheme member if we check to make sure it was one of these
// two options.
static cdm::InputBuffer_1 ConvertToInputBuffer_1(
const cdm::InputBuffer_2& aInputBuffer) {
MOZ_ASSERT(
IsEncryptionSchemeSupported(aInputBuffer.encryption_scheme),
"Encryption scheme should be checked before attempting conversion!");
return {aInputBuffer.data, aInputBuffer.data_size,
aInputBuffer.key_id, aInputBuffer.key_id_size,
aInputBuffer.iv, aInputBuffer.iv_size,
aInputBuffer.subsamples, aInputBuffer.num_subsamples,
aInputBuffer.timestamp};
}
static cdm::AudioDecoderConfig_1 ConverToAudioDecoderConfig_1(
const cdm::AudioDecoderConfig_2& aAudioConfig) {
MOZ_ASSERT(
IsEncryptionSchemeSupported(aAudioConfig.encryption_scheme),
"Encryption scheme should be checked before attempting conversion!");
return {aAudioConfig.codec,
aAudioConfig.channel_count,
aAudioConfig.bits_per_channel,
aAudioConfig.samples_per_second,
aAudioConfig.extra_data,
aAudioConfig.extra_data_size};
}
static cdm::VideoDecoderConfig_1 ConvertToVideoDecoderConfig_1(
const cdm::VideoDecoderConfig_2& aVideoConfig) {
MOZ_ASSERT(
IsEncryptionSchemeSupported(aVideoConfig.encryption_scheme),
"Encryption scheme should be checked before attempting conversion!");
return {aVideoConfig.codec, aVideoConfig.profile,
aVideoConfig.format, aVideoConfig.coded_size,
aVideoConfig.extra_data, aVideoConfig.extra_data_size};
}
}; // class ChromiumCDM9BackwardsCompat
mozilla::ipc::IPCResult GMPContentChild::RecvPChromiumCDMConstructor(
PChromiumCDMChild* aActor) {
ChromiumCDMChild* child = static_cast<ChromiumCDMChild*>(aActor);
@ -290,16 +91,8 @@ mozilla::ipc::IPCResult GMPContentChild::RecvPChromiumCDMConstructor(
void* cdm = nullptr;
GMPErr err = mGMPChild->GetAPI(CHROMIUM_CDM_API, host10, &cdm);
if (err != GMPNoErr || !cdm) {
// Try to create older version 9 CDM.
cdm::Host_9* host9 = child;
GMPErr err =
mGMPChild->GetAPI(CHROMIUM_CDM_API_BACKWARD_COMPAT, host9, &cdm);
if (err != GMPNoErr || !cdm) {
NS_WARNING("GMPGetAPI call failed trying to get CDM.");
return IPC_FAIL_NO_REASON(this);
}
cdm = new ChromiumCDM9BackwardsCompat(
host10, static_cast<cdm::ContentDecryptionModule_9*>(cdm));
NS_WARNING("GMPGetAPI call failed trying to get CDM.");
return IPC_FAIL_NO_REASON(this);
}
child->Init(static_cast<cdm::ContentDecryptionModule_10*>(cdm),