Bug 1845946 - Part 1. Switch GMP process launching IPDL messages from sync to async. r=ipc-reviewers,media-playback-reviewers,alwu,mccr8

When launching the GMP process, or querying its state, via PGMPService,
the design was already asynchronous. As such we can remove the sync
requirement quite easily and allow more flexibility on the parent
process side.

Differential Revision: https://phabricator.services.mozilla.com/D185335
This commit is contained in:
Andrew Osmond 2023-08-15 16:46:12 +00:00
parent b981925956
commit 25c238ea4e
14 changed files with 270 additions and 154 deletions

View File

@ -17,6 +17,10 @@ namespace mozilla::gmp {
class GMPChild;
/**
* This class allows the GMP process to receive requests to create GMP
* decoder/encoder objects on behalf of the parent/content processes.
*/
class GMPContentChild : public PGMPContentChild, public GMPSharedMem {
public:
// Mark AddRef and Release as `final`, as they overload pure virtual

View File

@ -199,4 +199,22 @@ nsresult GMPContentParent::GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE) {
return NS_OK;
}
void GMPContentParentCloseBlocker::Destroy() {
MOZ_ASSERT(mParent);
MOZ_ASSERT(mEventTarget);
if (!mEventTarget->IsOnCurrentThread()) {
mEventTarget->Dispatch(NS_NewRunnableFunction(
__func__, [parent = std::move(mParent), eventTarget = mEventTarget]() {
parent->RemoveCloseBlocker();
}));
mEventTarget = nullptr;
return;
}
mParent->RemoveCloseBlocker();
mParent = nullptr;
mEventTarget = nullptr;
}
} // namespace mozilla::gmp

View File

@ -13,11 +13,16 @@
namespace mozilla::gmp {
class GMPContentParentCloseBlocker;
class GMPParent;
class GMPVideoDecoderParent;
class GMPVideoEncoderParent;
class ChromiumCDMParent;
/**
* This class allows the parent/content processes to create GMP decoder/encoder
* objects in the GMP process.
*/
class GMPContentParent final : public PGMPContentParent, public GMPSharedMem {
friend class PGMPContentParent;
@ -52,20 +57,9 @@ class GMPContentParent final : public PGMPContentParent, public GMPSharedMem {
void SetPluginType(GMPPluginType aPluginType) { mPluginType = aPluginType; }
GMPPluginType GetPluginType() const { return mPluginType; }
class CloseBlocker {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CloseBlocker)
explicit CloseBlocker(GMPContentParent* aParent) : mParent(aParent) {
mParent->AddCloseBlocker();
}
RefPtr<GMPContentParent> mParent;
private:
~CloseBlocker() { mParent->RemoveCloseBlocker(); }
};
private:
friend class GMPContentParentCloseBlocker;
void AddCloseBlocker();
void RemoveCloseBlocker();
@ -89,6 +83,26 @@ class GMPContentParent final : public PGMPContentParent, public GMPSharedMem {
uint32_t mCloseBlockerCount = 0;
};
class GMPContentParentCloseBlocker final {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPContentParentCloseBlocker)
explicit GMPContentParentCloseBlocker(GMPContentParent* aParent)
: mParent(aParent), mEventTarget(aParent->GMPEventTarget()) {
MOZ_ASSERT(mEventTarget);
mParent->AddCloseBlocker();
}
void Destroy();
RefPtr<GMPContentParent> mParent;
private:
nsCOMPtr<nsISerialEventTarget> mEventTarget;
~GMPContentParentCloseBlocker() { Destroy(); }
};
} // namespace mozilla::gmp
#endif // GMPParent_h_

View File

@ -1095,8 +1095,8 @@ void GMPParent::ResolveGetContentParentPromises() {
nsTArray<UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>> promises =
std::move(mGetContentParentPromises);
MOZ_ASSERT(mGetContentParentPromises.IsEmpty());
RefPtr<GMPContentParent::CloseBlocker> blocker(
new GMPContentParent::CloseBlocker(mGMPContentParent));
RefPtr<GMPContentParentCloseBlocker> blocker(
new GMPContentParentCloseBlocker(mGMPContentParent));
for (auto& holder : promises) {
holder->Resolve(blocker, __func__);
}
@ -1143,8 +1143,8 @@ void GMPParent::GetGMPContentParent(
GMP_PARENT_LOG_DEBUG("%s %p", __FUNCTION__, this);
if (mGMPContentParent) {
RefPtr<GMPContentParent::CloseBlocker> blocker(
new GMPContentParent::CloseBlocker(mGMPContentParent));
RefPtr<GMPContentParentCloseBlocker> blocker(
new GMPContentParentCloseBlocker(mGMPContentParent));
aPromiseHolder->Resolve(blocker, __func__);
} else {
mGetContentParentPromises.AppendElement(std::move(aPromiseHolder));

View File

@ -257,7 +257,7 @@ RefPtr<GetCDMParentPromise> GeckoMediaPluginService::GetCDM(
->Then(
thread, __func__,
[rawHolder, helper, keySystem = nsCString{aKeySystem}](
RefPtr<GMPContentParent::CloseBlocker> wrapper) {
const RefPtr<GMPContentParentCloseBlocker>& wrapper) {
RefPtr<GMPContentParent> parent = wrapper->mParent;
MOZ_ASSERT(
parent,
@ -319,7 +319,7 @@ GeckoMediaPluginService::GetContentParentForTest() {
nsLiteralCString(CHROMIUM_CDM_API), tags)
->Then(
thread, __func__,
[rawHolder](const RefPtr<GMPContentParent::CloseBlocker>& wrapper) {
[rawHolder](const RefPtr<GMPContentParentCloseBlocker>& wrapper) {
RefPtr<GMPContentParent> parent = wrapper->mParent;
MOZ_ASSERT(
parent,
@ -460,7 +460,7 @@ GeckoMediaPluginService::GetGMPVideoDecoder(
->Then(
thread, __func__,
[rawCallback,
helper](RefPtr<GMPContentParent::CloseBlocker> wrapper) {
helper](const RefPtr<GMPContentParentCloseBlocker>& wrapper) {
RefPtr<GMPContentParent> parent = wrapper->mParent;
UniquePtr<GetGMPVideoDecoderCallback> callback(rawCallback);
GMPVideoDecoderParent* actor = nullptr;
@ -500,7 +500,7 @@ GeckoMediaPluginService::GetGMPVideoEncoder(
->Then(
thread, __func__,
[rawCallback,
helper](RefPtr<GMPContentParent::CloseBlocker> wrapper) {
helper](const RefPtr<GMPContentParentCloseBlocker>& wrapper) {
RefPtr<GMPContentParent> parent = wrapper->mParent;
UniquePtr<GetGMPVideoEncoderCallback> callback(rawCallback);
GMPVideoEncoderParent* actor = nullptr;

View File

@ -38,12 +38,11 @@ extern GMPLogLevel GetGMPLibraryLogLevel();
namespace gmp {
typedef MozPromise<RefPtr<GMPContentParent::CloseBlocker>, MediaResult,
/* IsExclusive = */ true>
GetGMPContentParentPromise;
typedef MozPromise<RefPtr<ChromiumCDMParent>, MediaResult,
/* IsExclusive = */ true>
GetCDMParentPromise;
using GetGMPContentParentPromise =
MozPromise<RefPtr<GMPContentParentCloseBlocker>, MediaResult,
/* IsExclusive = */ true>;
using GetCDMParentPromise = MozPromise<RefPtr<ChromiumCDMParent>, MediaResult,
/* IsExclusive = */ true>;
class GeckoMediaPluginService : public mozIGeckoMediaPluginService,
public nsIObserver {

View File

@ -5,7 +5,6 @@
#include "GMPServiceChild.h"
#include "GMPContentParent.h"
#include "GMPLog.h"
#include "GMPParent.h"
#include "base/task.h"
@ -122,67 +121,112 @@ GeckoMediaPluginServiceChild::GetContentParent(
thread, __func__,
[nodeIdVariant = aNodeIdVariant, self, api, tags = aTags.Clone(), helper,
rawHolder](GMPServiceChild* child) {
UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>> holder(
rawHolder);
nsresult rv;
nsTArray<base::ProcessId> alreadyBridgedTo;
child->GetAlreadyBridgedTo(alreadyBridgedTo);
base::ProcessId otherProcess;
nsCString displayName;
uint32_t pluginId = 0;
GMPPluginType pluginType = GMPPluginType::Unknown;
ipc::Endpoint<PGMPContentParent> endpoint;
nsCString errorDescription;
// We want to force the content process to keep all of our
// GMPContentParent IPDL objects alive while we wait to resolve which
// process can satisfy our request. This avoids a race condition where
// the last dependency is released before we can acquire our own.
auto* rawBlockers =
new nsTArray<RefPtr<GMPContentParentCloseBlocker>>();
child->GetAndBlockAlreadyBridgedTo(alreadyBridgedTo, *rawBlockers);
bool ok = child->SendLaunchGMP(
nodeIdVariant, api, tags, alreadyBridgedTo, &pluginId, &pluginType,
&otherProcess, &displayName, &endpoint, &rv, &errorDescription);
child->SendLaunchGMP(
nodeIdVariant, api, tags, alreadyBridgedTo,
[rawHolder, self, helper, rawBlockers,
child = RefPtr{child}](GMPLaunchResult&& aResult) {
UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>> holder(
rawHolder);
UniquePtr<nsTArray<RefPtr<GMPContentParentCloseBlocker>>>
blockers(rawBlockers);
if (helper && aResult.pluginId()) {
// Note: Even if the launch failed, we need to connect the crash
// helper so that if the launch failed due to the plugin
// crashing, we can report the crash via the crash reporter. The
// crash handling notification will arrive shortly if the launch
// failed due to the plugin crashing.
self->ConnectCrashHelper(aResult.pluginId(), helper);
}
if (helper && pluginId) {
// Note: Even if the launch failed, we need to connect the crash
// helper so that if the launch failed due to the plugin crashing, we
// can report the crash via the crash reporter. The crash handling
// notification will arrive shortly if the launch failed due to the
// plugin crashing.
self->ConnectCrashHelper(pluginId, helper);
}
if (NS_WARN_IF(NS_FAILED(aResult.result()))) {
MediaResult error(
aResult.result(),
nsPrintfCString(
"GeckoMediaPluginServiceChild::GetContentParent "
"SendLaunchGMPForNodeId failed with description (%s)",
aResult.errorDescription().get()));
if (!ok || NS_FAILED(rv)) {
MediaResult error(
rv, nsPrintfCString(
"GeckoMediaPluginServiceChild::GetContentParent "
"SendLaunchGMPForNodeId failed with description (%s)",
errorDescription.get()));
GMP_LOG_DEBUG("%s failed to launch GMP with error: %s",
__CLASS__, aResult.errorDescription().get());
self->mPendingGetContentParents -= 1;
self->RemoveShutdownBlockerIfNeeded();
GMP_LOG_DEBUG("%s failed to launch GMP with error: %s", __CLASS__,
error.Description().get());
self->mPendingGetContentParents -= 1;
self->RemoveShutdownBlockerIfNeeded();
holder->Reject(error, __func__);
return;
}
holder->Reject(error, __func__);
return;
}
// If we didn't explicitly fail, we should have been told about a
// process running.
MOZ_ASSERT(aResult.pid() != base::kInvalidProcessId);
RefPtr<GMPContentParent> parent = child->GetBridgedGMPContentParent(
otherProcess, std::move(endpoint));
if (!alreadyBridgedTo.Contains(otherProcess)) {
parent->SetDisplayName(displayName);
parent->SetPluginId(pluginId);
parent->SetPluginType(pluginType);
}
// It is possible the GMP process may have terminated before we
// were able to process this result. In that case, we should just
// fail as normal as the initialization of the IPDL objects would
// have just failed anyways and produced the same result.
bool contains = child->HasAlreadyBridgedTo(aResult.pid());
if (NS_WARN_IF(!contains && !aResult.endpoint().IsValid())) {
MediaResult error(
aResult.result(),
"GeckoMediaPluginServiceChild::GetContentParent "
"SendLaunchGMPForNodeId failed with process exit"_ns);
// The content parent is no longer pending.
self->mPendingGetContentParents -= 1;
MOZ_ASSERT(child->HaveContentParents(),
"We should have at least one content parent!");
// We don't check if we need to remove the shutdown blocker here as
// we should always have at least one live content parent.
GMP_LOG_DEBUG("%s failed to launch GMP with process exit",
__CLASS__);
self->mPendingGetContentParents -= 1;
self->RemoveShutdownBlockerIfNeeded();
RefPtr<GMPContentParent::CloseBlocker> blocker(
new GMPContentParent::CloseBlocker(parent));
holder->Resolve(blocker, __func__);
holder->Reject(error, __func__);
return;
}
RefPtr<GMPContentParent> parent =
child->GetBridgedGMPContentParent(
aResult.pid(), std::move(aResult.endpoint()));
if (!contains) {
parent->SetDisplayName(aResult.displayName());
parent->SetPluginId(aResult.pluginId());
parent->SetPluginType(aResult.pluginType());
}
// The content parent is no longer pending.
self->mPendingGetContentParents -= 1;
MOZ_ASSERT(child->HaveContentParents(),
"We should have at least one content parent!");
// We don't check if we need to remove the shutdown blocker here
// as we should always have at least one live content parent.
RefPtr<GMPContentParentCloseBlocker> blocker(
new GMPContentParentCloseBlocker(parent));
holder->Resolve(blocker, __func__);
},
[rawHolder, self, helper,
rawBlockers](const ipc::ResponseRejectReason&) {
UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>> holder(
rawHolder);
UniquePtr<nsTArray<RefPtr<GMPContentParentCloseBlocker>>>
blockers(rawBlockers);
MediaResult error(
NS_ERROR_FAILURE,
"GeckoMediaPluginServiceChild::GetContentParent "
"SendLaunchGMPForNodeId failed with IPC error"_ns);
GMP_LOG_DEBUG("%s failed to launch GMP with IPC error",
__CLASS__);
self->mPendingGetContentParents -= 1;
self->RemoveShutdownBlockerIfNeeded();
holder->Reject(error, __func__);
});
},
[self, rawHolder](MediaResult result) {
self->mPendingGetContentParents -= 1;
@ -320,14 +364,16 @@ GeckoMediaPluginServiceChild::GetNodeId(
GetServiceChild()->Then(
thread, __func__,
[rawCallback, origin, topLevelOrigin, gmpName](GMPServiceChild* child) {
UniquePtr<GetNodeIdCallback> callback(rawCallback);
nsCString outId;
if (!child->SendGetGMPNodeId(origin, topLevelOrigin, gmpName, &outId)) {
callback->Done(NS_ERROR_FAILURE, ""_ns);
return;
}
callback->Done(NS_OK, outId);
child->SendGetGMPNodeId(
origin, topLevelOrigin, gmpName,
[rawCallback](nsCString&& aId) {
UniquePtr<GetNodeIdCallback> callback(rawCallback);
callback->Done(NS_OK, aId);
},
[rawCallback](const ipc::ResponseRejectReason&) {
UniquePtr<GetNodeIdCallback> callback(rawCallback);
callback->Done(NS_ERROR_FAILURE, ""_ns);
});
},
[rawCallback](nsresult rv) {
UniquePtr<GetNodeIdCallback> callback(rawCallback);
@ -504,9 +550,19 @@ void GMPServiceChild::RemoveGMPContentParent(
}
}
void GMPServiceChild::GetAlreadyBridgedTo(
nsTArray<base::ProcessId>& aAlreadyBridgedTo) {
AppendToArray(aAlreadyBridgedTo, mContentParents.Keys());
bool GMPServiceChild::HasAlreadyBridgedTo(base::ProcessId aPid) const {
return mContentParents.Contains(aPid);
}
void GMPServiceChild::GetAndBlockAlreadyBridgedTo(
nsTArray<base::ProcessId>& aAlreadyBridgedTo,
nsTArray<RefPtr<GMPContentParentCloseBlocker>>& aBlockers) {
aAlreadyBridgedTo.SetCapacity(mContentParents.Count());
aBlockers.SetCapacity(mContentParents.Count());
for (auto iter = mContentParents.Iter(); !iter.Done(); iter.Next()) {
aAlreadyBridgedTo.AppendElement(iter.Key());
aBlockers.AppendElement(new GMPContentParentCloseBlocker(iter.UserData()));
}
}
class OpenPGMPServiceChild : public mozilla::Runnable {

View File

@ -18,6 +18,7 @@
namespace mozilla::gmp {
class GMPContentParent;
class GMPContentParentCloseBlocker;
class GMPServiceChild;
class GeckoMediaPluginServiceChild : public GeckoMediaPluginService,
@ -132,6 +133,10 @@ class GeckoMediaPluginServiceChild : public GeckoMediaPluginService,
// End shutdown blocker management.
};
/**
* This class runs in the content process, and allows the content process to
* request an IPC connection to the desired GMP process.
*/
class GMPServiceChild : public PGMPServiceChild {
public:
// Mark AddRef and Release as `final`, as they overload pure virtual
@ -145,7 +150,11 @@ class GMPServiceChild : public PGMPServiceChild {
void RemoveGMPContentParent(GMPContentParent* aGMPContentParent);
void GetAlreadyBridgedTo(nsTArray<ProcessId>& aAlreadyBridgedTo);
bool HasAlreadyBridgedTo(base::ProcessId aPid) const;
void GetAndBlockAlreadyBridgedTo(
nsTArray<ProcessId>& aAlreadyBridgedTo,
nsTArray<RefPtr<GMPContentParentCloseBlocker>>& aBlockers);
static bool Create(Endpoint<PGMPServiceChild>&& aGMPService);

View File

@ -1794,82 +1794,94 @@ GMPServiceParent::~GMPServiceParent() {
mozilla::ipc::IPCResult GMPServiceParent::RecvLaunchGMP(
const NodeIdVariant& aNodeIdVariant, const nsACString& aAPI,
nsTArray<nsCString>&& aTags, nsTArray<ProcessId>&& aAlreadyBridgedTo,
uint32_t* aOutPluginId, GMPPluginType* aOutPluginType,
ProcessId* aOutProcessId, nsCString* aOutDisplayName,
Endpoint<PGMPContentParent>* aOutEndpoint, nsresult* aOutRv,
nsCString* aOutErrorDescription) {
LaunchGMPResolver&& aResolve) {
GMPLaunchResult result;
if (mService->IsShuttingDown()) {
*aOutRv = NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
*aOutErrorDescription = "Service is shutting down."_ns;
*aOutPluginId = 0;
*aOutPluginType = GMPPluginType::Unknown;
result.pluginId() = 0;
result.pluginType() = GMPPluginType::Unknown;
result.pid() = base::kInvalidProcessId;
result.result() = NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
result.errorDescription() = "Service is shutting down."_ns;
aResolve(std::move(result));
return IPC_OK();
}
nsCString nodeIdString;
nsresult rv = mService->GetNodeId(aNodeIdVariant, nodeIdString);
if (!NS_SUCCEEDED(rv)) {
*aOutRv = rv;
*aOutErrorDescription = "GetNodeId failed."_ns;
*aOutPluginId = 0;
*aOutPluginType = GMPPluginType::Unknown;
if (NS_WARN_IF(NS_FAILED(rv))) {
result.pluginId() = 0;
result.pluginType() = GMPPluginType::Unknown;
result.pid() = base::kInvalidProcessId;
result.result() = rv;
result.errorDescription() = "GetNodeId failed."_ns;
aResolve(std::move(result));
return IPC_OK();
}
RefPtr<GMPParent> gmp =
mService->SelectPluginForAPI(nodeIdString, aAPI, aTags);
if (gmp) {
*aOutPluginId = gmp->GetPluginId();
*aOutPluginType = gmp->GetPluginType();
result.pluginId() = gmp->GetPluginId();
result.pluginType() = gmp->GetPluginType();
} else {
*aOutRv = NS_ERROR_FAILURE;
*aOutErrorDescription = "SelectPluginForAPI returns nullptr."_ns;
*aOutPluginId = 0;
*aOutPluginType = GMPPluginType::Unknown;
result.pluginId() = 0;
result.pluginType() = GMPPluginType::Unknown;
result.pid() = base::kInvalidProcessId;
result.result() = NS_ERROR_FAILURE;
result.errorDescription() = "SelectPluginForAPI returns nullptr."_ns;
aResolve(std::move(result));
return IPC_OK();
}
if (!gmp->EnsureProcessLoaded(aOutProcessId)) {
*aOutRv = NS_ERROR_FAILURE;
*aOutErrorDescription = "Process has not loaded."_ns;
if (!gmp->EnsureProcessLoaded(&result.pid())) {
result.pid() = base::kInvalidProcessId;
result.result() = NS_ERROR_FAILURE;
result.errorDescription() = "Process has not loaded."_ns;
aResolve(std::move(result));
return IPC_OK();
}
*aOutDisplayName = gmp->GetDisplayName();
MOZ_ASSERT(result.pid() != base::kInvalidProcessId);
if (aAlreadyBridgedTo.Contains(*aOutProcessId)) {
*aOutRv = NS_OK;
result.displayName() = gmp->GetDisplayName();
if (aAlreadyBridgedTo.Contains(result.pid())) {
result.result() = NS_OK;
aResolve(std::move(result));
return IPC_OK();
}
Endpoint<PGMPContentParent> parent;
Endpoint<PGMPContentChild> child;
rv =
PGMPContent::CreateEndpoints(OtherPid(), *aOutProcessId, &parent, &child);
rv = PGMPContent::CreateEndpoints(OtherPid(), result.pid(), &parent, &child);
if (NS_WARN_IF(NS_FAILED(rv))) {
*aOutRv = rv;
*aOutErrorDescription = "PGMPContent::CreateEndpoints failed."_ns;
result.result() = rv;
result.errorDescription() = "PGMPContent::CreateEndpoints failed."_ns;
aResolve(std::move(result));
return IPC_OK();
}
*aOutEndpoint = std::move(parent);
if (!gmp->SendInitGMPContentChild(std::move(child))) {
*aOutRv = NS_ERROR_FAILURE;
*aOutErrorDescription = "SendInitGMPContentChild failed."_ns;
result.result() = NS_ERROR_FAILURE;
result.errorDescription() = "SendInitGMPContentChild failed."_ns;
return IPC_OK();
}
gmp->IncrementGMPContentChildCount();
*aOutRv = NS_OK;
result.result() = NS_OK;
result.endpoint() = std::move(parent);
aResolve(std::move(result));
return IPC_OK();
}
mozilla::ipc::IPCResult GMPServiceParent::RecvGetGMPNodeId(
const nsAString& aOrigin, const nsAString& aTopLevelOrigin,
const nsAString& aGMPName, nsCString* aID) {
nsresult rv = mService->GetNodeId(aOrigin, aTopLevelOrigin, aGMPName, *aID);
const nsAString& aGMPName, GetGMPNodeIdResolver&& aResolve) {
nsCString id;
nsresult rv = mService->GetNodeId(aOrigin, aTopLevelOrigin, aGMPName, id);
aResolve(id);
if (!NS_SUCCEEDED(rv)) {
return IPC_FAIL(
this,

View File

@ -239,6 +239,11 @@ bool MatchOrigin(nsIFile* aPath, const nsACString& aSite,
const mozilla::OriginAttributesPattern& aPattern);
bool MatchBaseDomain(nsIFile* aPath, const nsACString& aBaseDomain);
/**
* This class runs in the parent process, and manages the lifecycle of the GMP
* process and brokering the creation of PGMPContent between the parent/content
* processes and the GMP process.
*/
class GMPServiceParent final : public PGMPServiceParent {
public:
explicit GMPServiceParent(GeckoMediaPluginServiceParent* aService);
@ -257,17 +262,15 @@ class GMPServiceParent final : public PGMPServiceParent {
ipc::IPCResult RecvGetGMPNodeId(const nsAString& aOrigin,
const nsAString& aTopLevelOrigin,
const nsAString& aGMPName,
nsCString* aID) override;
GetGMPNodeIdResolver&& aResolve) override;
static bool Create(Endpoint<PGMPServiceParent>&& aGMPService);
ipc::IPCResult RecvLaunchGMP(
const NodeIdVariant& aNodeIdVariant, const nsACString& aAPI,
nsTArray<nsCString>&& aTags, nsTArray<ProcessId>&& aAlreadyBridgedTo,
uint32_t* aOutPluginId, GMPPluginType* aOutPluginType,
ProcessId* aOutProcessId, nsCString* aOutDisplayName,
Endpoint<PGMPContentParent>* aOutEndpoint, nsresult* aOutRv,
nsCString* aOutErrorDescription) override;
ipc::IPCResult RecvLaunchGMP(const NodeIdVariant& aNodeIdVariant,
const nsACString& aAPI,
nsTArray<nsCString>&& aTags,
nsTArray<ProcessId>&& aAlreadyBridgedTo,
LaunchGMPResolver&& aResolve) override;
private:
~GMPServiceParent();

View File

@ -6,29 +6,34 @@
include protocol PGMPContent;
include GMPTypes;
using mozilla::ipc::Endpoint from "mozilla/ipc/Endpoint.h";
using base::ProcessId from "base/process.h";
using GMPPluginType from "GMPNativeTypes.h";
namespace mozilla {
namespace gmp {
struct GMPLaunchResult {
uint32_t pluginId;
GMPPluginType pluginType;
ProcessId pid;
nsCString displayName;
Endpoint<PGMPContentParent> endpoint;
nsresult result;
nsCString errorDescription;
};
[NeedsOtherPid, ChildImpl=virtual, ParentImpl=virtual]
sync protocol PGMPService
async protocol PGMPService
{
parent:
sync LaunchGMP(NodeIdVariant nodeIdVariant,
nsCString api,
nsCString[] tags,
ProcessId[] alreadyBridgedTo)
returns (uint32_t pluginId,
GMPPluginType pluginType,
ProcessId id,
nsCString displayName,
Endpoint<PGMPContentParent> endpoint,
nsresult aResult,
nsCString aErrorDescription);
async LaunchGMP(NodeIdVariant nodeIdVariant,
nsCString api,
nsCString[] tags,
ProcessId[] alreadyBridgedTo)
returns (GMPLaunchResult aResult);
sync GetGMPNodeId(nsString origin, nsString topLevelOrigin, nsString gmpName)
async GetGMPNodeId(nsString origin, nsString topLevelOrigin, nsString gmpName)
returns (nsCString id);
child:
async BeginShutdown();

View File

@ -84,10 +84,6 @@ description = for bug 1514869 - layout is blocked on font lookup, needs complete
description = for bug 1487212 - layout requires hyphenation data from a given omnijar resource - only called once per locale by a given content process
[PGMP::StartPlugin]
description = legacy sync IPC - please add detailed description
[PGMPService::LaunchGMP]
description = legacy sync IPC - please add detailed description
[PGMPService::GetGMPNodeId]
description = legacy sync IPC - please add detailed description
[PGMPVideoDecoder::NeedShmem]
description = legacy sync IPC - please add detailed description
[PGMPVideoEncoder::NeedShmem]

View File

@ -202,7 +202,7 @@ SandboxTest::StartTests(const nsTArray<nsCString>& aProcessesList) {
service->GetContentParentForTest()->Then(
thread, __func__,
[self, processPromise](
const RefPtr<gmp::GMPContentParent::CloseBlocker>&
const RefPtr<gmp::GMPContentParentCloseBlocker>&
wrapper) {
RefPtr<gmp::GMPContentParent> parent = wrapper->mParent;
MOZ_ASSERT(parent,

View File

@ -35,7 +35,7 @@ class SandboxTest : public mozISandboxTest {
private:
virtual ~SandboxTest() = default;
nsTArray<RefPtr<SandboxTestingParent>> mSandboxTestingParents;
RefPtr<gmp::GMPContentParent::CloseBlocker> mGMPContentParentWrapper;
RefPtr<gmp::GMPContentParentCloseBlocker> mGMPContentParentWrapper;
#if defined(XP_WIN)
bool mChromeDirExisted = false;
#endif