mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1042373 - Implement GMPDecryptor interface for use in GMPs. r=jesup
This commit is contained in:
parent
2de855d731
commit
fe2c056b8e
@ -6,6 +6,7 @@
|
||||
#include "GMPChild.h"
|
||||
#include "GMPVideoDecoderChild.h"
|
||||
#include "GMPVideoEncoderChild.h"
|
||||
#include "GMPDecryptorChild.h"
|
||||
#include "GMPVideoHost.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
@ -189,6 +190,19 @@ GMPChild::DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor)
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPDecryptorChild*
|
||||
GMPChild::AllocPGMPDecryptorChild()
|
||||
{
|
||||
return new GMPDecryptorChild(this);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPVideoEncoderChild*
|
||||
GMPChild::AllocPGMPVideoEncoderChild()
|
||||
{
|
||||
@ -234,5 +248,22 @@ GMPChild::RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPChild::RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor)
|
||||
{
|
||||
GMPDecryptorChild* child = static_cast<GMPDecryptorChild*>(aActor);
|
||||
GMPDecryptorHost* host = static_cast<GMPDecryptorHost*>(child);
|
||||
|
||||
void* session = nullptr;
|
||||
GMPErr err = mGetAPIFunc("eme-decrypt", host, &session);
|
||||
if (err != GMPNoErr || !session) {
|
||||
return false;
|
||||
}
|
||||
|
||||
child->Init(static_cast<GMPDecryptor*>(session));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
@ -29,12 +29,19 @@ public:
|
||||
private:
|
||||
virtual PCrashReporterChild* AllocPCrashReporterChild(const NativeThreadId& aThread) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPCrashReporterChild(PCrashReporterChild*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor) MOZ_OVERRIDE;
|
||||
virtual bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PGMPVideoEncoderChild* AllocPGMPVideoEncoderChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor) MOZ_OVERRIDE;
|
||||
virtual bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor) MOZ_OVERRIDE;
|
||||
virtual bool RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PGMPDecryptorChild* AllocPGMPDecryptorChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor) MOZ_OVERRIDE;
|
||||
virtual bool RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
virtual void ProcessingError(Result aWhat) MOZ_OVERRIDE;
|
||||
|
||||
|
328
content/media/gmp/GMPDecryptorChild.cpp
Normal file
328
content/media/gmp/GMPDecryptorChild.cpp
Normal file
@ -0,0 +1,328 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPDecryptorChild.h"
|
||||
#include "GMPChild.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include <ctime>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPDecryptorChild::GMPDecryptorChild(GMPChild* aPlugin)
|
||||
: mPlugin(aPlugin)
|
||||
, mSession(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin);
|
||||
}
|
||||
|
||||
GMPDecryptorChild::~GMPDecryptorChild()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::Init(GMPDecryptor* aSession)
|
||||
{
|
||||
MOZ_ASSERT(aSession);
|
||||
mSession = aSession;
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
nsAutoCString id(aSessionId, aSessionIdLength);
|
||||
SendResolveNewSessionPromise(aPromiseId, id);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::ResolvePromise(uint32_t aPromiseId)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
SendResolvePromise(aPromiseId);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::RejectPromise(uint32_t aPromiseId,
|
||||
GMPDOMException aException,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
nsAutoCString msg(aMessage, aMessageLength);
|
||||
SendRejectPromise(aPromiseId, aException, msg);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SessionMessage(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aMessage,
|
||||
uint32_t aMessageLength,
|
||||
const char* aDestinationURL,
|
||||
uint32_t aDestinationURLLength)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
nsAutoCString id(aSessionId, aSessionIdLength);
|
||||
nsTArray<uint8_t> msg;
|
||||
msg.AppendElements(aMessage, aMessageLength);
|
||||
nsAutoCString url(aDestinationURL, aDestinationURLLength);
|
||||
SendSessionMessage(id, msg, url);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::ExpirationChange(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPTimestamp aExpiryTime)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
nsAutoCString id(aSessionId, aSessionIdLength);
|
||||
SendExpirationChange(id, aExpiryTime);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SessionClosed(const char* aSessionId,
|
||||
uint32_t aSessionIdLength)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
nsAutoCString id(aSessionId, aSessionIdLength);
|
||||
SendSessionClosed(id);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SessionError(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPDOMException aException,
|
||||
uint32_t aSystemCode,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
nsAutoCString id(aSessionId, aSessionIdLength);
|
||||
nsAutoCString msg(aMessage, aMessageLength);
|
||||
SendSessionError(id, aException, aSystemCode, msg);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::KeyIdUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
nsAutoCString sid(aSessionId, aSessionIdLength);
|
||||
nsAutoTArray<uint8_t, 16> kid;
|
||||
kid.AppendElements(aKeyId, aKeyIdLength);
|
||||
SendKeyIdUsable(sid, kid);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::KeyIdNotUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
nsAutoCString sid(aSessionId, aSessionIdLength);
|
||||
nsAutoTArray<uint8_t, 16> kid;
|
||||
kid.AppendElements(aKeyId, aKeyIdLength);
|
||||
SendKeyIdNotUsable(sid, kid);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::Decrypted(GMPBuffer* aBuffer, GMPErr aResult)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
auto buffer = static_cast<GMPBufferImpl*>(aBuffer);
|
||||
SendDecrypted(buffer->mId, aResult, buffer->mData);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SetCapabilities(uint64_t aCaps)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
SendSetCaps(aCaps);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::GetNodeId(const char** aOutNodeId,
|
||||
uint32_t* aOutNodeIdLength)
|
||||
{
|
||||
static const char* id = "placeholder_node_id";
|
||||
*aOutNodeId = id;
|
||||
*aOutNodeIdLength = strlen(id);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::GetSandboxVoucher(const uint8_t** aVoucher,
|
||||
uint8_t* aVoucherLength)
|
||||
{
|
||||
const char* voucher = "placeholder_sandbox_voucher.";
|
||||
*aVoucher = (uint8_t*)voucher;
|
||||
*aVoucherLength = strlen(voucher);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::GetPluginVoucher(const uint8_t** aVoucher,
|
||||
uint8_t* aVoucherLength)
|
||||
{
|
||||
const char* voucher = "placeholder_plugin_voucher.";
|
||||
*aVoucher = (uint8_t*)voucher;
|
||||
*aVoucherLength = strlen(voucher);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvInit()
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
mSession->Init(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvCreateSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aInitDataType,
|
||||
const nsTArray<uint8_t>& aInitData,
|
||||
const GMPSessionType& aSessionType)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->CreateSession(aPromiseId,
|
||||
aInitDataType.get(),
|
||||
aInitDataType.Length(),
|
||||
aInitData.Elements(),
|
||||
aInitData.Length(),
|
||||
aSessionType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvLoadSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->LoadSession(aPromiseId,
|
||||
aSessionId.get(),
|
||||
aSessionId.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvUpdateSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aResponse)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->UpdateSession(aPromiseId,
|
||||
aSessionId.get(),
|
||||
aSessionId.Length(),
|
||||
aResponse.Elements(),
|
||||
aResponse.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvCloseSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->CloseSession(aPromiseId,
|
||||
aSessionId.get(),
|
||||
aSessionId.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvRemoveSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->RemoveSession(aPromiseId,
|
||||
aSessionId.get(),
|
||||
aSessionId.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvSetServerCertificate(const uint32_t& aPromiseId,
|
||||
const nsTArray<uint8_t>& aServerCert)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->SetServerCertificate(aPromiseId,
|
||||
aServerCert.Elements(),
|
||||
aServerCert.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvDecrypt(const uint32_t& aId,
|
||||
const nsTArray<uint8_t>& aBuffer,
|
||||
const GMPDecryptionData& aMetadata)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GMPEncryptedBufferDataImpl metadata(aMetadata);
|
||||
|
||||
mSession->Decrypt(new GMPBufferImpl(aId, aBuffer), &metadata);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvDecryptingComplete()
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->DecryptingComplete();
|
||||
mSession = nullptr;
|
||||
|
||||
unused << Send__delete__(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
127
content/media/gmp/GMPDecryptorChild.h
Normal file
127
content/media/gmp/GMPDecryptorChild.h
Normal file
@ -0,0 +1,127 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GMPDecryptorChild_h_
|
||||
#define GMPDecryptorChild_h_
|
||||
|
||||
#include "mozilla/gmp/PGMPDecryptorChild.h"
|
||||
#include "gmp-decryption.h"
|
||||
#include "mozilla/gmp/GMPTypes.h"
|
||||
#include "GMPEncryptedBufferDataImpl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPChild;
|
||||
|
||||
class GMPDecryptorChild : public GMPDecryptorCallback
|
||||
, public GMPDecryptorHost
|
||||
, public PGMPDecryptorChild
|
||||
{
|
||||
public:
|
||||
GMPDecryptorChild(GMPChild* aPlugin);
|
||||
~GMPDecryptorChild();
|
||||
|
||||
void Init(GMPDecryptor* aSession);
|
||||
|
||||
// GMPDecryptorCallback
|
||||
virtual void ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) MOZ_OVERRIDE;
|
||||
virtual void ResolvePromise(uint32_t aPromiseId) MOZ_OVERRIDE;
|
||||
|
||||
virtual void RejectPromise(uint32_t aPromiseId,
|
||||
GMPDOMException aException,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SessionMessage(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aMessage,
|
||||
uint32_t aMessageLength,
|
||||
const char* aDestinationURL,
|
||||
uint32_t aDestinationURLLength) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ExpirationChange(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPTimestamp aExpiryTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SessionClosed(const char* aSessionId,
|
||||
uint32_t aSessionIdLength) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SessionError(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPDOMException aException,
|
||||
uint32_t aSystemCode,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength) MOZ_OVERRIDE;
|
||||
|
||||
virtual void KeyIdUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength) MOZ_OVERRIDE;
|
||||
|
||||
virtual void KeyIdNotUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetCapabilities(uint64_t aCaps) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Decrypted(GMPBuffer* aBuffer, GMPErr aResult) MOZ_OVERRIDE;
|
||||
|
||||
// GMPDecryptorHost
|
||||
virtual void GetNodeId(const char** aOutNodeId,
|
||||
uint32_t* aOutNodeIdLength) MOZ_OVERRIDE;
|
||||
|
||||
virtual void GetSandboxVoucher(const uint8_t** aVoucher,
|
||||
uint8_t* aVoucherLength) MOZ_OVERRIDE;
|
||||
|
||||
virtual void GetPluginVoucher(const uint8_t** aVoucher,
|
||||
uint8_t* aVoucherLength) MOZ_OVERRIDE;
|
||||
private:
|
||||
|
||||
// GMPDecryptorChild
|
||||
virtual bool RecvInit() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvCreateSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aInitDataType,
|
||||
const nsTArray<uint8_t>& aInitData,
|
||||
const GMPSessionType& aSessionType) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvLoadSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvUpdateSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aResponse) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvCloseSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvRemoveSession(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvDecrypt(const uint32_t& aId,
|
||||
const nsTArray<uint8_t>& aBuffer,
|
||||
const GMPDecryptionData& aMetadata);
|
||||
|
||||
// Resolve/reject promise on completion.
|
||||
virtual bool RecvSetServerCertificate(const uint32_t& aPromiseId,
|
||||
const nsTArray<uint8_t>& aServerCert) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvDecryptingComplete() MOZ_OVERRIDE;
|
||||
|
||||
GMPChild* mPlugin;
|
||||
|
||||
// GMP's GMPDecryptor implementation.
|
||||
// Only call into this on the (GMP process) main thread.
|
||||
GMPDecryptor* mSession;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GMPDecryptorChild_h_
|
358
content/media/gmp/GMPDecryptorParent.cpp
Normal file
358
content/media/gmp/GMPDecryptorParent.cpp
Normal file
@ -0,0 +1,358 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPDecryptorParent.h"
|
||||
#include "GMPParent.h"
|
||||
#include "mp4_demuxer/DecoderData.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPDecryptorParent::GMPDecryptorParent(GMPParent* aPlugin)
|
||||
: mIsOpen(false)
|
||||
, mPlugin(aPlugin)
|
||||
, mCallback(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin);
|
||||
}
|
||||
|
||||
GMPDecryptorParent::~GMPDecryptorParent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPDecryptorParent::Init(GMPDecryptorProxyCallback* aCallback)
|
||||
{
|
||||
if (mIsOpen) {
|
||||
NS_WARNING("Trying to re-use an in-use GMP decrypter!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mCallback = aCallback;
|
||||
if (!SendInit()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mIsOpen = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorParent::CreateSession(uint32_t aPromiseId,
|
||||
const nsCString& aInitDataType,
|
||||
const nsTArray<uint8_t>& aInitData,
|
||||
GMPSessionType aSessionType)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return;
|
||||
}
|
||||
// Caller should ensure parameters passed in from JS are valid.
|
||||
MOZ_ASSERT(!aInitDataType.IsEmpty() && !aInitData.IsEmpty());
|
||||
unused << SendCreateSession(aPromiseId, aInitDataType, aInitData, aSessionType);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorParent::LoadSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return;
|
||||
}
|
||||
// Caller should ensure parameters passed in from JS are valid.
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
unused << SendLoadSession(aPromiseId, aSessionId);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorParent::UpdateSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aResponse)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return;
|
||||
}
|
||||
// Caller should ensure parameters passed in from JS are valid.
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty() && !aResponse.IsEmpty());
|
||||
unused << SendUpdateSession(aPromiseId, aSessionId, aResponse);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorParent::CloseSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return;
|
||||
}
|
||||
// Caller should ensure parameters passed in from JS are valid.
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
unused << SendCloseSession(aPromiseId, aSessionId);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorParent::RemoveSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return;
|
||||
}
|
||||
// Caller should ensure parameters passed in from JS are valid.
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
unused << SendRemoveSession(aPromiseId, aSessionId);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorParent::SetServerCertificate(uint32_t aPromiseId,
|
||||
const nsTArray<uint8_t>& aServerCert)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return;
|
||||
}
|
||||
// Caller should ensure parameters passed in from JS are valid.
|
||||
MOZ_ASSERT(!aServerCert.IsEmpty());
|
||||
unused << SendSetServerCertificate(aPromiseId, aServerCert);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorParent::Decrypt(uint32_t aId,
|
||||
const mp4_demuxer::CryptoSample& aCrypto,
|
||||
const nsTArray<uint8_t>& aBuffer)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Caller should ensure parameters passed in are valid.
|
||||
MOZ_ASSERT(!aBuffer.IsEmpty() && aCrypto.valid);
|
||||
|
||||
GMPDecryptionData data(aCrypto.key,
|
||||
aCrypto.iv,
|
||||
aCrypto.plain_sizes,
|
||||
aCrypto.encrypted_sizes);
|
||||
|
||||
unused << SendDecrypt(aId, aBuffer, data);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvResolveNewSessionPromise(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->ResolveNewSessionPromise(aPromiseId, aSessionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvResolvePromise(const uint32_t& aPromiseId)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->ResolvePromise(aPromiseId);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPExToNsresult(GMPDOMException aDomException) {
|
||||
switch (aDomException) {
|
||||
case kGMPNoModificationAllowedError: return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
case kGMPNotFoundError: return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
case kGMPNotSupportedError: return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
case kGMPInvalidStateError: return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
case kGMPSyntaxError: return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
case kGMPInvalidModificationError: return NS_ERROR_DOM_INVALID_MODIFICATION_ERR;
|
||||
case kGMPInvalidAccessError: return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
case kGMPSecurityError: return NS_ERROR_DOM_SECURITY_ERR;
|
||||
case kGMPAbortError: return NS_ERROR_DOM_ABORT_ERR;
|
||||
case kGMPQuotaExceededError: return NS_ERROR_DOM_QUOTA_EXCEEDED_ERR;
|
||||
case kGMPTimeoutError: return NS_ERROR_DOM_TIMEOUT_ERR;
|
||||
default: return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvRejectPromise(const uint32_t& aPromiseId,
|
||||
const GMPDOMException& aException,
|
||||
const nsCString& aMessage)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->RejectPromise(aPromiseId, GMPExToNsresult(aException), aMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvSessionMessage(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aMessage,
|
||||
const nsCString& aDestinationURL)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->SessionMessage(aSessionId, aMessage, aDestinationURL);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvExpirationChange(const nsCString& aSessionId,
|
||||
const double& aExpiryTime)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->ExpirationChange(aSessionId, aExpiryTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvSessionClosed(const nsCString& aSessionId)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->SessionClosed(aSessionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvSessionError(const nsCString& aSessionId,
|
||||
const GMPDOMException& aException,
|
||||
const uint32_t& aSystemCode,
|
||||
const nsCString& aMessage)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->SessionError(aSessionId,
|
||||
GMPExToNsresult(aException),
|
||||
aSystemCode,
|
||||
aMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvKeyIdUsable(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aKeyId)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->KeyIdUsable(aSessionId, aKeyId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvKeyIdNotUsable(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aKeyId)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->KeyIdNotUsable(aSessionId, aKeyId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvSetCaps(const uint64_t& aCaps)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->SetCaps(aCaps);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvDecrypted(const uint32_t& aId,
|
||||
const GMPErr& aErr,
|
||||
const nsTArray<uint8_t>& aBuffer)
|
||||
{
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->Decrypted(aId, aErr, aBuffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Note: may be called via Terminated()
|
||||
void
|
||||
GMPDecryptorParent::Close()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
// Consumer is done with us; we can shut down. No more callbacks should
|
||||
// be made to mCallback. Note: do this before Shutdown()!
|
||||
mCallback = nullptr;
|
||||
// Let Shutdown mark us as dead so it knows if we had been alive
|
||||
|
||||
// In case this is the last reference
|
||||
nsRefPtr<GMPDecryptorParent> kungfudeathgrip(this);
|
||||
NS_RELEASE(kungfudeathgrip);
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorParent::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
// Notify client we're gone! Won't occur after Close()
|
||||
if (mCallback) {
|
||||
mCallback->Terminated();
|
||||
mCallback = nullptr;
|
||||
}
|
||||
|
||||
if (mIsOpen) {
|
||||
mIsOpen = false;
|
||||
unused << SendDecryptingComplete();
|
||||
}
|
||||
}
|
||||
|
||||
// Note: Keep this sync'd up with Shutdown
|
||||
void
|
||||
GMPDecryptorParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
mIsOpen = false;
|
||||
if (mCallback) {
|
||||
// May call Close() (and Shutdown()) immediately or with a delay
|
||||
mCallback->Terminated();
|
||||
mCallback = nullptr;
|
||||
}
|
||||
if (mPlugin) {
|
||||
mPlugin->DecryptorDestroyed(this);
|
||||
mPlugin = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::Recv__delete__()
|
||||
{
|
||||
if (mPlugin) {
|
||||
mPlugin->DecryptorDestroyed(this);
|
||||
mPlugin = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
113
content/media/gmp/GMPDecryptorParent.h
Normal file
113
content/media/gmp/GMPDecryptorParent.h
Normal file
@ -0,0 +1,113 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GMPDecryptorParent_h_
|
||||
#define GMPDecryptorParent_h_
|
||||
|
||||
#include "mozilla/gmp/PGMPDecryptorParent.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "gmp-decryption.h"
|
||||
#include "GMPDecryptorProxy.h"
|
||||
namespace mp4_demuxer {
|
||||
class CryptoSample;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
|
||||
class GMPDecryptorParent MOZ_FINAL : public GMPDecryptorProxy
|
||||
, public PGMPDecryptorParent
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(GMPDecryptorParent)
|
||||
|
||||
GMPDecryptorParent(GMPParent *aPlugin);
|
||||
|
||||
// GMPDecryptorProxy
|
||||
virtual nsresult Init(GMPDecryptorProxyCallback* aCallback) MOZ_OVERRIDE;
|
||||
|
||||
virtual void CreateSession(uint32_t aPromiseId,
|
||||
const nsCString& aInitDataType,
|
||||
const nsTArray<uint8_t>& aInitData,
|
||||
GMPSessionType aSessionType) MOZ_OVERRIDE;
|
||||
|
||||
virtual void LoadSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual void UpdateSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aResponse) MOZ_OVERRIDE;
|
||||
|
||||
virtual void CloseSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual void RemoveSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetServerCertificate(uint32_t aPromiseId,
|
||||
const nsTArray<uint8_t>& aServerCert) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Decrypt(uint32_t aId,
|
||||
const mp4_demuxer::CryptoSample& aCrypto,
|
||||
const nsTArray<uint8_t>& aBuffer) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Close() MOZ_OVERRIDE;
|
||||
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
~GMPDecryptorParent();
|
||||
|
||||
// PGMPDecryptorParent
|
||||
|
||||
virtual bool RecvResolveNewSessionPromise(const uint32_t& aPromiseId,
|
||||
const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvResolvePromise(const uint32_t& aPromiseId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvRejectPromise(const uint32_t& aPromiseId,
|
||||
const GMPDOMException& aException,
|
||||
const nsCString& aMessage) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvSessionMessage(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aMessage,
|
||||
const nsCString& aDestinationURL) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvExpirationChange(const nsCString& aSessionId,
|
||||
const double& aExpiryTime) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvSessionClosed(const nsCString& aSessionId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvSessionError(const nsCString& aSessionId,
|
||||
const GMPDOMException& aException,
|
||||
const uint32_t& aSystemCode,
|
||||
const nsCString& aMessage) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvKeyIdUsable(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aKeyId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvKeyIdNotUsable(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aKeyId) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvDecrypted(const uint32_t& aId,
|
||||
const GMPErr& aErr,
|
||||
const nsTArray<uint8_t>& aBuffer) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvSetCaps(const uint64_t& aCaps) MOZ_OVERRIDE;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
||||
|
||||
bool mIsOpen;
|
||||
nsRefPtr<GMPParent> mPlugin;
|
||||
GMPDecryptorProxyCallback* mCallback;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GMPDecryptorChild_h_
|
89
content/media/gmp/GMPDecryptorProxy.h
Normal file
89
content/media/gmp/GMPDecryptorProxy.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GMPDecryptorProxy_h_
|
||||
#define GMPDecryptorProxy_h_
|
||||
|
||||
#include "GMPCallbackBase.h"
|
||||
|
||||
namespace mp4_demuxer {
|
||||
class CryptoSample;
|
||||
}
|
||||
|
||||
class GMPDecryptorProxyCallback : public GMPCallbackBase {
|
||||
public:
|
||||
~GMPDecryptorProxyCallback() {}
|
||||
|
||||
virtual void ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId) = 0;
|
||||
|
||||
virtual void ResolvePromise(uint32_t aPromiseId) = 0;
|
||||
|
||||
virtual void RejectPromise(uint32_t aPromiseId,
|
||||
nsresult aException,
|
||||
const nsCString& aSessionId) = 0;
|
||||
|
||||
virtual void SessionMessage(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aMessage,
|
||||
const nsCString& aDestinationURL) = 0;
|
||||
|
||||
virtual void ExpirationChange(const nsCString& aSessionId,
|
||||
GMPTimestamp aExpiryTime) = 0;
|
||||
|
||||
virtual void SessionClosed(const nsCString& aSessionId) = 0;
|
||||
|
||||
virtual void SessionError(const nsCString& aSessionId,
|
||||
nsresult aException,
|
||||
uint32_t aSystemCode,
|
||||
const nsCString& aMessage) = 0;
|
||||
|
||||
virtual void KeyIdUsable(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aKeyId) = 0;
|
||||
|
||||
virtual void KeyIdNotUsable(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aKeyId) = 0;
|
||||
|
||||
virtual void SetCaps(uint64_t aCaps) = 0;
|
||||
|
||||
virtual void Decrypted(uint32_t aId,
|
||||
GMPErr aResult,
|
||||
const nsTArray<uint8_t>& aDecryptedData) = 0;
|
||||
};
|
||||
|
||||
class GMPDecryptorProxy {
|
||||
public:
|
||||
~GMPDecryptorProxy() {}
|
||||
|
||||
virtual nsresult Init(GMPDecryptorProxyCallback* aCallback) = 0;
|
||||
|
||||
virtual void CreateSession(uint32_t aPromiseId,
|
||||
const nsCString& aInitDataType,
|
||||
const nsTArray<uint8_t>& aInitData,
|
||||
GMPSessionType aSessionType) = 0;
|
||||
|
||||
virtual void LoadSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId) = 0;
|
||||
|
||||
virtual void UpdateSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aResponse) = 0;
|
||||
|
||||
virtual void CloseSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId) = 0;
|
||||
|
||||
virtual void RemoveSession(uint32_t aPromiseId,
|
||||
const nsCString& aSessionId) = 0;
|
||||
|
||||
virtual void SetServerCertificate(uint32_t aPromiseId,
|
||||
const nsTArray<uint8_t>& aServerCert) = 0;
|
||||
|
||||
virtual void Decrypt(uint32_t aId,
|
||||
const mp4_demuxer::CryptoSample& aCrypto,
|
||||
const nsTArray<uint8_t>& aBuffer) = 0;
|
||||
|
||||
virtual void Close() = 0;
|
||||
};
|
||||
|
||||
#endif // GMPDecryptorProxy_h_
|
84
content/media/gmp/GMPEncryptedBufferDataImpl.cpp
Normal file
84
content/media/gmp/GMPEncryptedBufferDataImpl.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GMPEncryptedBufferDataImpl.h"
|
||||
#include "mozilla/gmp/GMPTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPEncryptedBufferDataImpl::GMPEncryptedBufferDataImpl(const CryptoSample& aCrypto)
|
||||
: mKeyId(aCrypto.key)
|
||||
, mIV(aCrypto.iv)
|
||||
, mClearBytes(aCrypto.plain_sizes)
|
||||
, mCipherBytes(aCrypto.encrypted_sizes)
|
||||
{
|
||||
}
|
||||
|
||||
GMPEncryptedBufferDataImpl::GMPEncryptedBufferDataImpl(const GMPDecryptionData& aData)
|
||||
{
|
||||
mKeyId = aData.mKeyId();
|
||||
mIV = aData.mIV();
|
||||
mClearBytes = aData.mClearBytes();
|
||||
mCipherBytes = aData.mCipherBytes();
|
||||
MOZ_ASSERT(mClearBytes.Length() == mCipherBytes.Length());
|
||||
}
|
||||
|
||||
void
|
||||
GMPEncryptedBufferDataImpl::RelinquishData(GMPDecryptionData& aData)
|
||||
{
|
||||
aData.mKeyId() = Move(mKeyId);
|
||||
aData.mIV() = Move(mIV);
|
||||
aData.mClearBytes() = Move(mClearBytes);
|
||||
aData.mCipherBytes() = Move(mCipherBytes);
|
||||
}
|
||||
|
||||
const uint8_t*
|
||||
GMPEncryptedBufferDataImpl::KeyId() const
|
||||
{
|
||||
return mKeyId.Elements();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GMPEncryptedBufferDataImpl::KeyIdSize() const
|
||||
{
|
||||
return mKeyId.Length();
|
||||
}
|
||||
|
||||
const uint8_t*
|
||||
GMPEncryptedBufferDataImpl::IV() const
|
||||
{
|
||||
return mIV.Elements();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GMPEncryptedBufferDataImpl::IVSize() const
|
||||
{
|
||||
return mIV.Length();
|
||||
}
|
||||
|
||||
const uint16_t*
|
||||
GMPEncryptedBufferDataImpl::ClearBytes() const
|
||||
{
|
||||
return mClearBytes.Elements();
|
||||
}
|
||||
|
||||
const uint32_t*
|
||||
GMPEncryptedBufferDataImpl::CipherBytes() const
|
||||
{
|
||||
return mCipherBytes.Elements();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GMPEncryptedBufferDataImpl::NumSubsamples() const
|
||||
{
|
||||
MOZ_ASSERT(mClearBytes.Length() == mCipherBytes.Length());
|
||||
// Return the min of the two, to ensure there's not chance of array index
|
||||
// out-of-bounds shenanigans.
|
||||
return std::min<uint32_t>(mClearBytes.Length(), mCipherBytes.Length());
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
68
content/media/gmp/GMPEncryptedBufferDataImpl.h
Normal file
68
content/media/gmp/GMPEncryptedBufferDataImpl.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GMPEncryptedBufferDataImpl_h_
|
||||
#define GMPEncryptedBufferDataImpl_h_
|
||||
|
||||
#include "gmp-decryption.h"
|
||||
#include "mp4_demuxer/DecoderData.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/gmp/GMPTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPEncryptedBufferDataImpl : public GMPEncryptedBufferMetadata {
|
||||
private:
|
||||
typedef mp4_demuxer::CryptoSample CryptoSample;
|
||||
public:
|
||||
GMPEncryptedBufferDataImpl(const CryptoSample& aCrypto);
|
||||
GMPEncryptedBufferDataImpl(const GMPDecryptionData& aData);
|
||||
|
||||
void RelinquishData(GMPDecryptionData& aData);
|
||||
|
||||
virtual const uint8_t* KeyId() const MOZ_OVERRIDE;
|
||||
virtual uint32_t KeyIdSize() const MOZ_OVERRIDE;
|
||||
virtual const uint8_t* IV() const MOZ_OVERRIDE;
|
||||
virtual uint32_t IVSize() const MOZ_OVERRIDE;
|
||||
virtual uint32_t NumSubsamples() const MOZ_OVERRIDE;
|
||||
virtual const uint16_t* ClearBytes() const MOZ_OVERRIDE;
|
||||
virtual const uint32_t* CipherBytes() const MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsTArray<uint8_t> mKeyId;
|
||||
nsTArray<uint8_t> mIV;
|
||||
nsTArray<uint16_t> mClearBytes;
|
||||
nsTArray<uint32_t> mCipherBytes;
|
||||
};
|
||||
|
||||
class GMPBufferImpl : public GMPBuffer {
|
||||
public:
|
||||
GMPBufferImpl(uint32_t aId, const nsTArray<uint8_t>& aData)
|
||||
: mId(aId)
|
||||
, mData(aData)
|
||||
{
|
||||
}
|
||||
virtual uint32_t Id() const {
|
||||
return mId;
|
||||
}
|
||||
virtual uint8_t* Data() {
|
||||
return mData.Elements();
|
||||
}
|
||||
virtual uint32_t Size() const {
|
||||
return mData.Length();
|
||||
}
|
||||
virtual void Resize(uint32_t aSize) {
|
||||
mData.SetLength(aSize);
|
||||
}
|
||||
|
||||
uint32_t mId;
|
||||
nsTArray<uint8_t> mData;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GMPEncryptedBufferDataImpl_h_
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "gmp-video-codec.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
#include "gmp-decryption.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
@ -18,6 +19,27 @@ struct ParamTraits<GMPErr>
|
||||
GMPLastErr>
|
||||
{};
|
||||
|
||||
struct GMPDomExceptionValidator {
|
||||
static bool IsLegalValue(GMPDOMException aValue) {
|
||||
switch (aValue) {
|
||||
case kGMPNoModificationAllowedError:
|
||||
case kGMPNotFoundError:
|
||||
case kGMPNotSupportedError:
|
||||
case kGMPInvalidStateError:
|
||||
case kGMPSyntaxError:
|
||||
case kGMPInvalidModificationError:
|
||||
case kGMPInvalidAccessError:
|
||||
case kGMPSecurityError:
|
||||
case kGMPAbortError:
|
||||
case kGMPQuotaExceededError:
|
||||
case kGMPTimeoutError:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPVideoFrameType>
|
||||
: public ContiguousEnumSerializer<GMPVideoFrameType,
|
||||
@ -25,6 +47,18 @@ struct ParamTraits<GMPVideoFrameType>
|
||||
kGMPSkipFrame>
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<GMPDOMException>
|
||||
: public EnumSerializer<GMPDOMException, GMPDomExceptionValidator>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPSessionType>
|
||||
: public ContiguousEnumSerializer<GMPSessionType,
|
||||
kGMPTemporySession,
|
||||
kGMPPersistentSession>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPVideoCodecComplexity>
|
||||
: public ContiguousEnumSerializer<GMPVideoCodecComplexity,
|
||||
|
@ -127,7 +127,8 @@ GMPParent::CloseIfUnused()
|
||||
mState == GMPStateLoaded ||
|
||||
mState == GMPStateUnloading) &&
|
||||
mVideoDecoders.IsEmpty() &&
|
||||
mVideoEncoders.IsEmpty()) {
|
||||
mVideoEncoders.IsEmpty() &&
|
||||
mDecryptors.IsEmpty()) {
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
@ -153,6 +154,11 @@ GMPParent::CloseActive(bool aDieWhenUnloaded)
|
||||
mVideoEncoders[i - 1]->Shutdown();
|
||||
}
|
||||
|
||||
// Invalidate and remove any remaining API objects.
|
||||
for (uint32_t i = mDecryptors.Length(); i > 0; i--) {
|
||||
mDecryptors[i - 1]->Shutdown();
|
||||
}
|
||||
|
||||
// Note: the shutdown of the codecs is async! don't kill
|
||||
// the plugin-container until they're all safely shut down via
|
||||
// CloseIfUnused();
|
||||
@ -225,6 +231,44 @@ GMPParent::VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GMPParent::DecryptorDestroyed(GMPDecryptorParent* aSession)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
MOZ_ALWAYS_TRUE(mDecryptors.RemoveElement(aSession));
|
||||
|
||||
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
|
||||
// until after this has completed.
|
||||
if (mDecryptors.IsEmpty()) {
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPParent::GetGMPDecryptor(GMPDecryptorParent** aGMPDP)
|
||||
{
|
||||
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!EnsureProcessLoaded()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PGMPDecryptorParent* pdp = SendPGMPDecryptorConstructor();
|
||||
if (!pdp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
GMPDecryptorParent* dp = static_cast<GMPDecryptorParent*>(pdp);
|
||||
// This addref corresponds to the Proxy pointer the consumer is returned.
|
||||
// It's dropped by calling Close() on the interface.
|
||||
NS_ADDREF(dp);
|
||||
mDecryptors.AppendElement(dp);
|
||||
*aGMPDP = dp;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
GMPState
|
||||
GMPParent::State() const
|
||||
{
|
||||
@ -461,6 +505,22 @@ GMPParent::DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor)
|
||||
return true;
|
||||
}
|
||||
|
||||
PGMPDecryptorParent*
|
||||
GMPParent::AllocPGMPDecryptorParent()
|
||||
{
|
||||
GMPDecryptorParent* ksp = new GMPDecryptorParent(this);
|
||||
NS_ADDREF(ksp);
|
||||
return ksp;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPParent::DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor)
|
||||
{
|
||||
GMPDecryptorParent* ksp = static_cast<GMPDecryptorParent*>(aActor);
|
||||
NS_RELEASE(ksp);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
ParseNextRecord(nsILineInputStream* aLineInputStream,
|
||||
const nsCString& aPrefix,
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define GMPParent_h_
|
||||
|
||||
#include "GMPProcessParent.h"
|
||||
#include "GMPDecryptorParent.h"
|
||||
#include "GMPVideoDecoderParent.h"
|
||||
#include "GMPVideoEncoderParent.h"
|
||||
#include "mozilla/gmp/PGMPParent.h"
|
||||
@ -73,10 +74,16 @@ public:
|
||||
void DeleteProcess();
|
||||
|
||||
bool SupportsAPI(const nsCString& aAPI, const nsCString& aTag);
|
||||
|
||||
nsresult GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD);
|
||||
void VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder);
|
||||
|
||||
nsresult GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE);
|
||||
void VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder);
|
||||
|
||||
nsresult GetGMPDecryptor(GMPDecryptorParent** aGMPKS);
|
||||
void DecryptorDestroyed(GMPDecryptorParent* aSession);
|
||||
|
||||
GMPState State() const;
|
||||
#ifdef DEBUG
|
||||
nsIThread* GMPThread();
|
||||
@ -119,11 +126,16 @@ private:
|
||||
|
||||
virtual PCrashReporterParent* AllocPCrashReporterParent(const NativeThreadId& aThread) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPCrashReporterParent(PCrashReporterParent* aCrashReporter) MOZ_OVERRIDE;
|
||||
|
||||
virtual PGMPVideoDecoderParent* AllocPGMPVideoDecoderParent() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PGMPVideoEncoderParent* AllocPGMPVideoEncoderParent() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PGMPDecryptorParent* AllocPGMPDecryptorParent() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor) MOZ_OVERRIDE;
|
||||
|
||||
GMPState mState;
|
||||
nsCOMPtr<nsIFile> mDirectory; // plugin directory on disk
|
||||
nsString mName; // base name of plugin on disk, UTF-16 because used for paths
|
||||
@ -136,6 +148,7 @@ private:
|
||||
|
||||
nsTArray<nsRefPtr<GMPVideoDecoderParent>> mVideoDecoders;
|
||||
nsTArray<nsRefPtr<GMPVideoEncoderParent>> mVideoEncoders;
|
||||
nsTArray<nsRefPtr<GMPDecryptorParent>> mDecryptors;
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIThread> mGMPThread;
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "GMPDecryptorParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -285,6 +286,37 @@ GeckoMediaPluginService::GetGMPVideoEncoder(nsTArray<nsCString>* aTags,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GeckoMediaPluginService::GetGMPDecryptor(nsTArray<nsCString>* aTags,
|
||||
const nsAString& aOrigin,
|
||||
GMPDecryptorProxy** aDecryptor)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
NS_ENSURE_ARG(aTags && aTags->Length() > 0);
|
||||
NS_ENSURE_ARG(aDecryptor);
|
||||
|
||||
if (mShuttingDownOnGMPThread) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(aOrigin,
|
||||
NS_LITERAL_CSTRING("eme-decrypt"),
|
||||
*aTags);
|
||||
if (!gmp) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
GMPDecryptorParent* ksp;
|
||||
nsresult rv = gmp->GetGMPDecryptor(&ksp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aDecryptor = static_cast<GMPDecryptorProxy*>(ksp);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GeckoMediaPluginService::UnloadPlugins()
|
||||
{
|
||||
|
@ -8,6 +8,13 @@ using GMPBufferType from "gmp-video-codec.h";
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
struct GMPDecryptionData {
|
||||
uint8_t[] mKeyId;
|
||||
uint8_t[] mIV;
|
||||
uint16_t[] mClearBytes;
|
||||
uint32_t[] mCipherBytes;
|
||||
};
|
||||
|
||||
struct GMPVideoEncodedFrameData
|
||||
{
|
||||
uint32_t mEncodedWidth;
|
||||
@ -19,6 +26,7 @@ struct GMPVideoEncodedFrameData
|
||||
GMPBufferType mBufferType;
|
||||
Shmem mBuffer;
|
||||
bool mCompleteFrame;
|
||||
GMPDecryptionData mDecryptionData;
|
||||
};
|
||||
|
||||
struct GMPPlaneData
|
||||
|
@ -6,6 +6,7 @@
|
||||
include protocol PGMPVideoDecoder;
|
||||
include protocol PGMPVideoEncoder;
|
||||
include protocol PCrashReporter;
|
||||
include protocol PGMPDecryptor;
|
||||
|
||||
using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h";
|
||||
|
||||
@ -14,6 +15,7 @@ namespace gmp {
|
||||
|
||||
intr protocol PGMP
|
||||
{
|
||||
manages PGMPDecryptor;
|
||||
manages PGMPVideoDecoder;
|
||||
manages PGMPVideoEncoder;
|
||||
manages PCrashReporter;
|
||||
@ -22,6 +24,7 @@ parent:
|
||||
async PCrashReporter(NativeThreadId tid);
|
||||
|
||||
child:
|
||||
async PGMPDecryptor();
|
||||
async PGMPVideoDecoder();
|
||||
async PGMPVideoEncoder();
|
||||
};
|
||||
|
85
content/media/gmp/PGMPDecryptor.ipdl
Normal file
85
content/media/gmp/PGMPDecryptor.ipdl
Normal file
@ -0,0 +1,85 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PGMP;
|
||||
include GMPTypes;
|
||||
|
||||
using GMPSessionType from "gmp-decryption.h";
|
||||
using GMPDOMException from "gmp-decryption.h";
|
||||
using GMPErr from "gmp-errors.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
async protocol PGMPDecryptor
|
||||
{
|
||||
manager PGMP;
|
||||
child:
|
||||
|
||||
Init();
|
||||
|
||||
CreateSession(uint32_t aPromiseId,
|
||||
nsCString aInitDataType,
|
||||
uint8_t[] aInitData,
|
||||
GMPSessionType aSessionType);
|
||||
|
||||
LoadSession(uint32_t aPromiseId,
|
||||
nsCString aSessionId);
|
||||
|
||||
UpdateSession(uint32_t aPromiseId,
|
||||
nsCString aSessionId,
|
||||
uint8_t[] aResponse);
|
||||
|
||||
CloseSession(uint32_t aPromiseId,
|
||||
nsCString aSessionId);
|
||||
|
||||
RemoveSession(uint32_t aPromiseId,
|
||||
nsCString aSessionId);
|
||||
|
||||
SetServerCertificate(uint32_t aPromiseId,
|
||||
uint8_t[] aServerCert);
|
||||
|
||||
Decrypt(uint32_t aId,
|
||||
uint8_t[] aBuffer,
|
||||
GMPDecryptionData aMetadata);
|
||||
|
||||
DecryptingComplete();
|
||||
|
||||
parent:
|
||||
__delete__();
|
||||
|
||||
ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
nsCString aSessionId);
|
||||
|
||||
ResolvePromise(uint32_t aPromiseId);
|
||||
|
||||
RejectPromise(uint32_t aPromiseId,
|
||||
GMPDOMException aDOMExceptionCode,
|
||||
nsCString aMessage);
|
||||
|
||||
SessionMessage(nsCString aSessionId,
|
||||
uint8_t[] aMessage,
|
||||
nsCString aDestinationURL);
|
||||
|
||||
ExpirationChange(nsCString aSessionId, double aExpiryTime);
|
||||
|
||||
SessionClosed(nsCString aSessionId);
|
||||
|
||||
SessionError(nsCString aSessionId,
|
||||
GMPDOMException aDOMExceptionCode,
|
||||
uint32_t aSystemCode,
|
||||
nsCString aMessage);
|
||||
|
||||
KeyIdUsable(nsCString aSessionId, uint8_t[] aKey);
|
||||
|
||||
SetCaps(uint64_t aCaps);
|
||||
|
||||
KeyIdNotUsable(nsCString aSessionId,uint8_t[] aKey);
|
||||
|
||||
Decrypted(uint32_t aId, GMPErr aResult, uint8_t[] aBuffer);
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
@ -31,6 +31,10 @@ EXPORTS += [
|
||||
'gmp-api/gmp-video-plane.h',
|
||||
'GMPCallbackBase.h',
|
||||
'GMPChild.h',
|
||||
'GMPDecryptorChild.h',
|
||||
'GMPDecryptorParent.h',
|
||||
'GMPDecryptorProxy.h',
|
||||
'GMPEncryptedBufferDataImpl.h',
|
||||
'GMPMessageUtils.h',
|
||||
'GMPParent.h',
|
||||
'GMPPlatform.h',
|
||||
@ -52,6 +56,9 @@ EXPORTS += [
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'GMPChild.cpp',
|
||||
'GMPDecryptorChild.cpp',
|
||||
'GMPDecryptorParent.cpp',
|
||||
'GMPEncryptedBufferDataImpl.cpp',
|
||||
'GMPParent.cpp',
|
||||
'GMPPlatform.cpp',
|
||||
'GMPProcessChild.cpp',
|
||||
@ -71,6 +78,7 @@ UNIFIED_SOURCES += [
|
||||
IPDL_SOURCES += [
|
||||
'GMPTypes.ipdlh',
|
||||
'PGMP.ipdl',
|
||||
'PGMPDecryptor.ipdl',
|
||||
'PGMPVideoDecoder.ipdl',
|
||||
'PGMPVideoEncoder.ipdl',
|
||||
]
|
||||
|
@ -10,6 +10,7 @@
|
||||
%{C++
|
||||
#include "nsTArray.h"
|
||||
#include "nsStringGlue.h"
|
||||
class GMPDecryptorProxy;
|
||||
class GMPVideoDecoderProxy;
|
||||
class GMPVideoEncoderProxy;
|
||||
class GMPVideoHost;
|
||||
@ -20,8 +21,9 @@ class GMPVideoHost;
|
||||
[ptr] native GMPVideoHost(GMPVideoHost);
|
||||
[ptr] native MessageLoop(MessageLoop);
|
||||
[ptr] native TagArray(nsTArray<nsCString>);
|
||||
[ptr] native GMPDecryptorProxy(GMPDecryptorProxy);
|
||||
|
||||
[scriptable, uuid(a9b826da-725a-4b81-814f-b715445188f2)]
|
||||
[scriptable, uuid(b301ea8b-8a1e-4839-a13c-9dd32b2d684b)]
|
||||
interface mozIGeckoMediaPluginService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -60,6 +62,12 @@ interface mozIGeckoMediaPluginService : nsISupports
|
||||
[optional] in AString origin,
|
||||
out GMPVideoHost outVideoHost);
|
||||
|
||||
// Returns a decryption session manager that supports the specified tags.
|
||||
// The array of tags should at least contain a key system tag, and optionally
|
||||
// other tags.
|
||||
// Callable only on GMP thread.
|
||||
GMPDecryptorProxy getGMPDecryptor(in TagArray tags, in AString origin);
|
||||
|
||||
/**
|
||||
* Add a directory to scan for gecko media plugins.
|
||||
* @note Main-thread API.
|
||||
|
Loading…
Reference in New Issue
Block a user