Bug 1321871, part 1 - Replace use of opens and bridges in GMP protocols with endpoints. r=peterv

This removes the open of PGMPContent from PGMP, the bridge of
PGMPService and PGMP from PGMPContent, and the spawn of PGMP from
PGMPService. I did these changes all at once because the way the
bridges works it was hard to split it up.

--HG--
extra : rebase_source : d9311e3047b9855ad422838f5a8b6bfdc382d225
This commit is contained in:
Andrew McCreight 2017-01-05 12:55:27 -08:00
Родитель d22c7ab8ed
Коммит 1951ea01ff
12 изменённых файлов: 80 добавлений и 62 удалений

Просмотреть файл

@ -24,11 +24,6 @@ include protocol PImageBridge;
include protocol PMedia;
include protocol PMemoryReportRequest;
include protocol PNecko;
// FIXME This is pretty ridiculous, but we have to keep the order of the
// following 4 includes, or the parser is confused about PGMPContent
// bridging PContent and PGMP. As soon as it registers the bridge between
// PContent and PPluginModule it seems to think that PContent's parent and
// child live in the same process!
include protocol PGMPContent;
include protocol PGMPService;
include protocol PPluginModule;

Просмотреть файл

@ -515,15 +515,13 @@ GMPChild::RecvCloseActive()
return IPC_OK();
}
PGMPContentChild*
GMPChild::AllocPGMPContentChild(Transport* aTransport,
ProcessId aOtherPid)
mozilla::ipc::IPCResult
GMPChild::RecvInitGMPContentChild(Endpoint<PGMPContentChild>&& aEndpoint)
{
GMPContentChild* child =
mGMPContentChildren.AppendElement(new GMPContentChild(this))->get();
child->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide);
return child;
aEndpoint.Bind(child);
return IPC_OK();
}
void

Просмотреть файл

@ -56,13 +56,13 @@ private:
PGMPStorageChild* AllocPGMPStorageChild() override;
bool DeallocPGMPStorageChild(PGMPStorageChild* aActor) override;
PGMPContentChild* AllocPGMPContentChild(Transport* aTransport,
ProcessId aOtherPid) override;
void GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild);
mozilla::ipc::IPCResult RecvCrashPluginNow() override;
mozilla::ipc::IPCResult RecvCloseActive() override;
mozilla::ipc::IPCResult RecvInitGMPContentChild(Endpoint<PGMPContentChild>&& aEndpoint) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
void ProcessingError(Result aCode, const char* aReason) override;

Просмотреть файл

@ -892,19 +892,32 @@ GMPParent::ResolveGetContentParentPromises()
}
}
PGMPContentParent*
GMPParent::AllocPGMPContentParent(Transport* aTransport, ProcessId aOtherPid)
bool
GMPParent::OpenPGMPContent()
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
MOZ_ASSERT(!mGMPContentParent);
Endpoint<PGMPContentParent> parent;
Endpoint<PGMPContentChild> child;
if (NS_FAILED(PGMPContent::CreateEndpoints(base::GetCurrentProcId(),
OtherPid(), &parent, &child))) {
return false;
}
mGMPContentParent = new GMPContentParent(this);
mGMPContentParent->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(),
ipc::ParentSide);
if (!parent.Bind(mGMPContentParent)) {
return false;
}
if (!SendInitGMPContentChild(Move(child))) {
return false;
}
ResolveGetContentParentPromises();
return mGMPContentParent;
return true;
}
void
@ -935,7 +948,7 @@ GMPParent::GetGMPContentParent(UniquePtr<MozPromiseHolder<GetGMPContentParentPro
// set then we should just store them, so that they get called when we set
// mGMPContentParent as a result of the PGMPContent::Open call.
if (mGetContentParentPromises.Length() == 1) {
if (!EnsureProcessLoaded() || !PGMPContent::Open(this)) {
if (!EnsureProcessLoaded() || !OpenPGMPContent()) {
RejectGetContentParentPromises();
return;
}
@ -964,14 +977,10 @@ GMPParent::EnsureProcessLoaded(base::ProcessId* aID)
return true;
}
bool
GMPParent::Bridge(GMPServiceParent* aGMPServiceParent)
void
GMPParent::IncrementGMPContentChildCount()
{
if (NS_FAILED(PGMPContent::Bridge(aGMPServiceParent, this))) {
return false;
}
++mGMPContentChildCount;
return true;
}
nsString

Просмотреть файл

@ -144,12 +144,14 @@ public:
// Called when the child process has died.
void ChildTerminated();
bool OpenPGMPContent();
void GetGMPContentParent(UniquePtr<MozPromiseHolder<GetGMPContentParentPromise>>&& aPromiseHolder);
already_AddRefed<GMPContentParent> ForgetGMPContentParent();
bool EnsureProcessLoaded(base::ProcessId* aID);
bool Bridge(GMPServiceParent* aGMPServiceParent);
void IncrementGMPContentChildCount();
const nsTArray<GMPCapability>& GetCapabilities() const { return mCapabilities; }
@ -175,9 +177,6 @@ private:
PGMPStorageParent* AllocPGMPStorageParent() override;
bool DeallocPGMPStorageParent(PGMPStorageParent* aActor) override;
PGMPContentParent* AllocPGMPContentParent(Transport* aTransport,
ProcessId aOtherPid) override;
mozilla::ipc::IPCResult RecvPGMPTimerConstructor(PGMPTimerParent* actor) override;
PGMPTimerParent* AllocPGMPTimerParent() override;
bool DeallocPGMPTimerParent(PGMPTimerParent* aActor) override;

Просмотреть файл

@ -80,6 +80,8 @@ GeckoMediaPluginServiceChild::GetContentParent(GMPCrashHelper* aHelper,
base::ProcessId otherProcess;
nsCString displayName;
uint32_t pluginId = 0;
ipc::Endpoint<PGMPContentParent> endpoint;
bool ok = child->SendLaunchGMP(nodeId,
api,
tags,
@ -87,7 +89,9 @@ GeckoMediaPluginServiceChild::GetContentParent(GMPCrashHelper* aHelper,
&pluginId,
&otherProcess,
&displayName,
&endpoint,
&rv);
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,
@ -103,12 +107,13 @@ GeckoMediaPluginServiceChild::GetContentParent(GMPCrashHelper* aHelper,
return;
}
RefPtr<GMPContentParent> parent;
child->GetBridgedGMPContentParent(otherProcess, getter_AddRefs(parent));
RefPtr<GMPContentParent> parent = child->GetBridgedGMPContentParent(otherProcess,
Move(endpoint));
if (!alreadyBridgedTo.Contains(otherProcess)) {
parent->SetDisplayName(displayName);
parent->SetPluginId(pluginId);
}
RefPtr<GMPContentParent::CloseBlocker> blocker(new GMPContentParent::CloseBlocker(parent));
holder->Resolve(blocker, __func__);
},
@ -339,31 +344,30 @@ GMPServiceChild::~GMPServiceChild()
{
}
PGMPContentParent*
GMPServiceChild::AllocPGMPContentParent(Transport* aTransport,
ProcessId aOtherPid)
already_AddRefed<GMPContentParent>
GMPServiceChild::GetBridgedGMPContentParent(ProcessId aOtherPid,
ipc::Endpoint<PGMPContentParent>&& endpoint)
{
MOZ_ASSERT(!mContentParents.GetWeak(aOtherPid));
RefPtr<GMPContentParent> parent;
mContentParents.Get(aOtherPid, getter_AddRefs(parent));
if (parent) {
return parent.forget();
}
MOZ_ASSERT(aOtherPid == endpoint.OtherPid());
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
MOZ_ASSERT(mainThread);
RefPtr<GMPContentParent> parent = new GMPContentParent();
parent = new GMPContentParent();
DebugOnly<bool> ok = parent->Open(aTransport, aOtherPid,
XRE_GetIOMessageLoop(),
mozilla::ipc::ParentSide);
DebugOnly<bool> ok = endpoint.Bind(parent);
MOZ_ASSERT(ok);
mContentParents.Put(aOtherPid, parent);
return parent;
}
void
GMPServiceChild::GetBridgedGMPContentParent(ProcessId aOtherPid,
GMPContentParent** aGMPContentParent)
{
mContentParents.Get(aOtherPid, aGMPContentParent);
return parent.forget();
}
void

Просмотреть файл

@ -70,11 +70,9 @@ public:
explicit GMPServiceChild();
virtual ~GMPServiceChild();
PGMPContentParent* AllocPGMPContentParent(Transport* aTransport,
ProcessId aOtherPid) override;
already_AddRefed<GMPContentParent> GetBridgedGMPContentParent(ProcessId aOtherPid,
ipc::Endpoint<PGMPContentParent>&& endpoint);
void GetBridgedGMPContentParent(ProcessId aOtherPid,
GMPContentParent** aGMPContentParent);
void RemoveGMPContentParent(GMPContentParent* aGMPContentParent);
void GetAlreadyBridgedTo(nsTArray<ProcessId>& aAlreadyBridgedTo);

Просмотреть файл

@ -1675,6 +1675,7 @@ GMPServiceParent::RecvLaunchGMP(const nsCString& aNodeId,
uint32_t* aOutPluginId,
ProcessId* aOutProcessId,
nsCString* aOutDisplayName,
Endpoint<PGMPContentParent>* aOutEndpoint,
nsresult* aOutRv)
{
if (mService->IsShuttingDown()) {
@ -1698,11 +1699,28 @@ GMPServiceParent::RecvLaunchGMP(const nsCString& aNodeId,
*aOutDisplayName = gmp->GetDisplayName();
if (!(aAlreadyBridgedTo.Contains(*aOutProcessId) || gmp->Bridge(this))) {
if (aAlreadyBridgedTo.Contains(*aOutProcessId)) {
*aOutRv = NS_OK;
return IPC_OK();
}
Endpoint<PGMPContentParent> parent;
Endpoint<PGMPContentChild> child;
if (NS_FAILED(PGMPContent::CreateEndpoints(OtherPid(), *aOutProcessId,
&parent, &child))) {
*aOutRv = NS_ERROR_FAILURE;
return IPC_OK();
}
*aOutEndpoint = Move(parent);
if (!gmp->SendInitGMPContentChild(Move(child))) {
*aOutRv = NS_ERROR_FAILURE;
return IPC_OK();
}
gmp->IncrementGMPContentChildCount();
*aOutRv = NS_OK;
return IPC_OK();
}

Просмотреть файл

@ -234,6 +234,7 @@ public:
uint32_t* aOutPluginId,
ProcessId* aOutID,
nsCString* aOutDisplayName,
Endpoint<PGMPContentParent>* aOutEndpoint,
nsresult* aOutRv) override;
private:

Просмотреть файл

@ -15,8 +15,6 @@ namespace gmp {
intr protocol PGMP
{
parent opens PGMPContent;
manages PCrashReporter;
manages PGMPTimer;
manages PGMPStorage;
@ -34,6 +32,7 @@ child:
async SetNodeId(nsCString nodeId);
async PreloadLibs(nsCString libs);
async CloseActive();
async InitGMPContentChild(Endpoint<PGMPContentChild> endpoint);
};
} // namespace gmp

Просмотреть файл

@ -3,8 +3,6 @@
* 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 protocol PGMPService;
include protocol PGMPVideoDecoder;
include protocol PGMPVideoEncoder;
include protocol PGMPDecryptor;
@ -14,8 +12,6 @@ namespace gmp {
intr protocol PGMPContent
{
bridges PGMPService, PGMP;
manages PGMPDecryptor;
manages PGMPVideoDecoder;
manages PGMPVideoEncoder;

Просмотреть файл

@ -3,7 +3,7 @@
* 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 protocol PGMPContent;
using base::ProcessId from "base/process.h";
@ -12,15 +12,16 @@ namespace gmp {
sync protocol PGMPService
{
parent spawns PGMP as child;
parent:
sync LaunchGMP(nsCString nodeId,
nsCString api,
nsCString[] tags,
ProcessId[] alreadyBridgedTo)
returns (uint32_t pluginId, ProcessId id, nsCString displayName, nsresult aResult);
returns (uint32_t pluginId,
ProcessId id,
nsCString displayName,
Endpoint<PGMPContentParent> endpoint,
nsresult aResult);
sync GetGMPNodeId(nsString origin, nsString topLevelOrigin, nsString gmpName)
returns (nsCString id);