mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-24 09:27:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
403
dom/media/gmp/GMPDecryptorChild.cpp
Normal file
403
dom/media/gmp/GMPDecryptorChild.cpp
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
/* -*- 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 "GMPContentChild.h"
|
||||
#include "GMPChild.h"
|
||||
#include "base/task.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "runnable_utils.h"
|
||||
#include <ctime>
|
||||
|
||||
#define ON_GMP_THREAD() (mPlugin->GMPMessageLoop() == MessageLoop::current())
|
||||
|
||||
#define CALL_ON_GMP_THREAD(_func, ...) \
|
||||
CallOnGMPThread(&GMPDecryptorChild::_func, __VA_ARGS__)
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
GMPDecryptorChild::GMPDecryptorChild(GMPContentChild* aPlugin,
|
||||
const nsTArray<uint8_t>& aPluginVoucher,
|
||||
const nsTArray<uint8_t>& aSandboxVoucher)
|
||||
: mSession(nullptr)
|
||||
, mPlugin(aPlugin)
|
||||
, mPluginVoucher(aPluginVoucher)
|
||||
, mSandboxVoucher(aSandboxVoucher)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin);
|
||||
}
|
||||
|
||||
GMPDecryptorChild::~GMPDecryptorChild()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename MethodType, typename... ParamType>
|
||||
void
|
||||
GMPDecryptorChild::CallMethod(MethodType aMethod, ParamType&&... aParams)
|
||||
{
|
||||
MOZ_ASSERT(ON_GMP_THREAD());
|
||||
// Don't send IPC messages after tear-down.
|
||||
if (mSession) {
|
||||
(this->*aMethod)(Forward<ParamType>(aParams)...);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct AddConstReference {
|
||||
typedef const typename RemoveReference<T>::Type& Type;
|
||||
};
|
||||
|
||||
template<typename MethodType, typename... ParamType>
|
||||
void
|
||||
GMPDecryptorChild::CallOnGMPThread(MethodType aMethod, ParamType&&... aParams)
|
||||
{
|
||||
if (ON_GMP_THREAD()) {
|
||||
// Use forwarding reference when we can.
|
||||
CallMethod(aMethod, Forward<ParamType>(aParams)...);
|
||||
} else {
|
||||
// Use const reference when we have to.
|
||||
auto m = &GMPDecryptorChild::CallMethod<
|
||||
decltype(aMethod), typename AddConstReference<ParamType>::Type...>;
|
||||
RefPtr<mozilla::Runnable> t =
|
||||
dont_add_new_uses_of_this::NewRunnableMethod(this, m, aMethod, Forward<ParamType>(aParams)...);
|
||||
mPlugin->GMPMessageLoop()->PostTask(t.forget());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::Init(GMPDecryptor* aSession)
|
||||
{
|
||||
MOZ_ASSERT(aSession);
|
||||
mSession = aSession;
|
||||
// The ID of this decryptor is the IPDL actor ID. Note it's unique inside
|
||||
// the child process, but not necessarily across all gecko processes. However,
|
||||
// since GMPDecryptors are segregated by node ID/origin, we shouldn't end up
|
||||
// with clashes in the content process.
|
||||
SendSetDecryptorId(Id());
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SetSessionId(uint32_t aCreateSessionToken,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendSetSessionId,
|
||||
aCreateSessionToken, nsCString(aSessionId, aSessionIdLength));
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::ResolveLoadSessionPromise(uint32_t aPromiseId,
|
||||
bool aSuccess)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendResolveLoadSessionPromise, aPromiseId, aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::ResolvePromise(uint32_t aPromiseId)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendResolvePromise, aPromiseId);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::RejectPromise(uint32_t aPromiseId,
|
||||
GMPDOMException aException,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendRejectPromise,
|
||||
aPromiseId, aException, nsCString(aMessage, aMessageLength));
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SessionMessage(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPSessionMessageType aMessageType,
|
||||
const uint8_t* aMessage,
|
||||
uint32_t aMessageLength)
|
||||
{
|
||||
nsTArray<uint8_t> msg;
|
||||
msg.AppendElements(aMessage, aMessageLength);
|
||||
CALL_ON_GMP_THREAD(SendSessionMessage,
|
||||
nsCString(aSessionId, aSessionIdLength),
|
||||
aMessageType, Move(msg));
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::ExpirationChange(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPTimestamp aExpiryTime)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendExpirationChange,
|
||||
nsCString(aSessionId, aSessionIdLength), aExpiryTime);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SessionClosed(const char* aSessionId,
|
||||
uint32_t aSessionIdLength)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendSessionClosed,
|
||||
nsCString(aSessionId, aSessionIdLength));
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SessionError(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPDOMException aException,
|
||||
uint32_t aSystemCode,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendSessionError,
|
||||
nsCString(aSessionId, aSessionIdLength),
|
||||
aException, aSystemCode,
|
||||
nsCString(aMessage, aMessageLength));
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::KeyStatusChanged(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength,
|
||||
GMPMediaKeyStatus aStatus)
|
||||
{
|
||||
AutoTArray<uint8_t, 16> kid;
|
||||
kid.AppendElements(aKeyId, aKeyIdLength);
|
||||
|
||||
nsTArray<GMPKeyInformation> keyInfos;
|
||||
keyInfos.AppendElement(GMPKeyInformation(kid, aStatus));
|
||||
CALL_ON_GMP_THREAD(SendBatchedKeyStatusChanged,
|
||||
nsCString(aSessionId, aSessionIdLength),
|
||||
keyInfos);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::BatchedKeyStatusChanged(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const GMPMediaKeyInfo* aKeyInfos,
|
||||
uint32_t aKeyInfosLength)
|
||||
{
|
||||
nsTArray<GMPKeyInformation> keyInfos;
|
||||
for (uint32_t i = 0; i < aKeyInfosLength; i++) {
|
||||
nsTArray<uint8_t> keyId;
|
||||
keyId.AppendElements(aKeyInfos[i].keyid, aKeyInfos[i].keyid_size);
|
||||
keyInfos.AppendElement(GMPKeyInformation(keyId, aKeyInfos[i].status));
|
||||
}
|
||||
CALL_ON_GMP_THREAD(SendBatchedKeyStatusChanged,
|
||||
nsCString(aSessionId, aSessionIdLength),
|
||||
keyInfos);
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::Decrypted(GMPBuffer* aBuffer, GMPErr aResult)
|
||||
{
|
||||
if (!ON_GMP_THREAD()) {
|
||||
// We should run this whole method on the GMP thread since the buffer needs
|
||||
// to be deleted after the SendDecrypted call.
|
||||
mPlugin->GMPMessageLoop()->PostTask(NewRunnableMethod
|
||||
<GMPBuffer*, GMPErr>(this,
|
||||
&GMPDecryptorChild::Decrypted,
|
||||
aBuffer, aResult));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aBuffer) {
|
||||
NS_WARNING("GMPDecryptorCallback passed bull GMPBuffer");
|
||||
return;
|
||||
}
|
||||
|
||||
auto buffer = static_cast<GMPBufferImpl*>(aBuffer);
|
||||
if (mSession) {
|
||||
SendDecrypted(buffer->mId, aResult, buffer->mData);
|
||||
}
|
||||
delete buffer;
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::SetCapabilities(uint64_t aCaps)
|
||||
{
|
||||
// Deprecated.
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::GetSandboxVoucher(const uint8_t** aVoucher,
|
||||
uint32_t* aVoucherLength)
|
||||
{
|
||||
if (!aVoucher || !aVoucherLength) {
|
||||
return;
|
||||
}
|
||||
*aVoucher = mSandboxVoucher.Elements();
|
||||
*aVoucherLength = mSandboxVoucher.Length();
|
||||
}
|
||||
|
||||
void
|
||||
GMPDecryptorChild::GetPluginVoucher(const uint8_t** aVoucher,
|
||||
uint32_t* aVoucherLength)
|
||||
{
|
||||
if (!aVoucher || !aVoucherLength) {
|
||||
return;
|
||||
}
|
||||
*aVoucher = mPluginVoucher.Elements();
|
||||
*aVoucherLength = mPluginVoucher.Length();
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvInit(const bool& aDistinctiveIdentifierRequired,
|
||||
const bool& aPersistentStateRequired)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
mSession->Init(this, aDistinctiveIdentifierRequired, aPersistentStateRequired);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvCreateSession(const uint32_t& aCreateSessionToken,
|
||||
const uint32_t& aPromiseId,
|
||||
const nsCString& aInitDataType,
|
||||
InfallibleTArray<uint8_t>&& aInitData,
|
||||
const GMPSessionType& aSessionType)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->CreateSession(aCreateSessionToken,
|
||||
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,
|
||||
InfallibleTArray<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,
|
||||
InfallibleTArray<uint8_t>&& aServerCert)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mSession->SetServerCertificate(aPromiseId,
|
||||
aServerCert.Elements(),
|
||||
aServerCert.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvDecrypt(const uint32_t& aId,
|
||||
InfallibleTArray<uint8_t>&& aBuffer,
|
||||
const GMPDecryptionData& aMetadata)
|
||||
{
|
||||
if (!mSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: the GMPBufferImpl created here is deleted when the GMP passes
|
||||
// it back in the Decrypted() callback above.
|
||||
GMPBufferImpl* buffer = new GMPBufferImpl(aId, aBuffer);
|
||||
|
||||
// |metadata| lifetime is managed by |buffer|.
|
||||
GMPEncryptedBufferDataImpl* metadata = new GMPEncryptedBufferDataImpl(aMetadata);
|
||||
buffer->SetMetadata(metadata);
|
||||
|
||||
mSession->Decrypt(buffer, metadata);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorChild::RecvDecryptingComplete()
|
||||
{
|
||||
// Reset |mSession| before calling DecryptingComplete(). We should not send
|
||||
// any IPC messages during tear-down.
|
||||
auto session = mSession;
|
||||
mSession = nullptr;
|
||||
|
||||
if (!session) {
|
||||
return false;
|
||||
}
|
||||
|
||||
session->DecryptingComplete();
|
||||
|
||||
Unused << Send__delete__(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gmp
|
||||
} // namespace mozilla
|
||||
|
||||
// avoid redefined macro in unified build
|
||||
#undef ON_GMP_THREAD
|
||||
#undef CALL_ON_GMP_THREAD
|
||||
Loading…
Add table
Add a link
Reference in a new issue